TypeScript wiki (TypeScript-Handbook/pages/Classes.md) first example - typescript1.8

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Classes.md
I'm trying to learn TypeScript. The first example in Classes:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
This seems straightforward, but when I log greeter: console.log(greeter);
instead of getting "Hello World" I get "Greeter {greeting: "world"}"
My setup:
package.json: (just TypeScript; no other libraries)
{
"name": "typescript learning",
"version": "1.0.0",
"scripts": {
"start": "concurrently \"npm run tsc:w\" \"npm run lite\" ",
"tsc": "tsc",
"tsc:w": "tsc -w",
"lite": "lite-server"
},
"license": "ISC",
"dependencies": {
"concurrently": "^2.0.0",
"lite-server": "^2.1.0",
"typescript": "^1.8.0"
}
}
and tsconfig.json just defaults:
{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules",
"typings/main",
"typings/main.d.ts",
"typescript.notes.ts"
]
}
So, am I missing something fundamental? Or is this just an incomplete example that shouldn't be evaluated? Obviously I'm still quite new to TypeScript and don't have any background to take examples apart from their face value. Many thanks for any input,
-Mike

Your problem is:
let greeter = new Greeter("world");
console.log(greeter);
This only shows the class instance itself, and doesn't actually call a method on the class.
So what you want is:
let greeter = new Greeter("world");
console.log(greeter.greet());
To also answer your question in the comments:
One quick question, even though the method greet is part of the class, It doesn't get evaluated by calling the class? I see this is the case, but again, not what I expected. I'm trying to get a model in my mind for using the class instead of separate function.
At its essence, a class is basically nothing more than a collection of methods and variables that logically "belong" together for some reason.
For example, if I have a class Car, it might have the variable fuel and the methods drive() and refuel(). Calling the drive() and refuel() methods would alter the variable fuel. This way, you can easily create one, two, or a hundred instances of one class, and still easily keep track of stuff. Without object-oriented-programming, all of that would be a lot harder to keep track off, especially when you start creating multiple cars.
Obviously, you don't want to immediately start drive() when creating a new car! There is the constructor method in your code, which does get run automatically every time a class is created. This is often useful to initialize some things, but is really nothing more than a shortcut for something like:
let greeter = new Greeter();
greeter.set_message("world")
Except that you can't forget it to use it ;-) The constructor is often used for variables that the class should always have, like the string in your example, or, in our Car example, setting the fuel to some initial level. Hence the name, it is needed to construct the class.
In the "real world" most classes are a bit more abstract, and there are some features which allow you to do more (like inheritance), but the basic idea is the same: a class is a collection if methods and variables that logically belong to the same "thing" or "object" − I feel some guides make this a lot more complicated than it needs to be by the way, as they immediately want to introduce concepts such as inheritance right from the start without fully explaining the basic purpose of classes.
Don't worry if you don't fully comprehend everything when you're just starting out. I think few people do. I certainly didn't. Almost everyone struggles with stuff like this at first.

greeter is an object. So, calling console.log(greeter); is logging an the actual object whose greeting property is set to world.
You want to log greeter.greet() in order to see "Hello, world."

Related

Is there precedence for object oriented syntax for a relative path?

I'm creating my own extended version of JSON for various reasons. One thing that I'm adding is the ability to self reference and I'm trying to come up with an OO syntax for relative paths.
To illustrate, lets say I have a nested object that is supposed to reference its parent object
{ my_item: { parent: ??? } }
??? symbolizes the missing syntax.
Now in most operating systems, going up one level is notated as .. so we could try doing the same
{ my_item: { parent: .. } }
Looks pretty neat, however, if I tried to reference anything else in the parent, I'd end up with
{ my_item_sibling: {}, my_item: { sibling_of_parent: ...my_item_sibling } }
Which is not as neat as its the same as spread syntax ... which I'm also adding
I could do something with parentheses, like so
{ my_item_sibling: {}, my_item: { sibling_of_parent: (..).my_item_sibling } }
Which is not terrible but I'd prefer something cleaner.
Maybe I'll reserve a symbol?
{ my_item_sibling: {}, my_item: { sibling_of_parent: #.my_item_sibling } }
In any case, these examples are just to illustrate what I'm doing. If there is an established or a particularly nice looking way to do it, I'll just copy that.
The question is: Is there a precedence to this? A relative path implemented in a c-like language?

Enforcing read-only attributes from the metaclass

Yes, still going with this. My impression is that there's this powerful facility in Raku, which is not really easy to use, and there's so little documentation for that. I'd like to kind of mitigate that.
In this case, I'm trying to force attributes to be read-only by default, to make immutable classes. Here's my attempt:
my class MetamodelX::Frozen is Metamodel::ClassHOW {
method compose_attributes($the-obj, :$compiler_services) {
my $attribute-container = callsame;
my $new-container = Perl6::Metamodel::AttributeContainer.new(
:attributes($attribute-container.attributes),
:attribute_lookup($attribute-container.attribute_table),
:0attr_rw_by_default
);
$new-container.compose_attributes($the-obj, $compiler_services);
}
}
my package EXPORTHOW {
package DECLARE {
constant frozen = MetamodelX::Frozen;
}
}
I'm calling that from a main function that looks like this:
use Frozen;
frozen Foo {
has $.bar;
method gist() {
return "→ $!bar";
}
}
my $foo = Foo.new(:3bar);
say $foo.bar;
$foo.bar(33);
I'm trying to follow the source, that does not really give a lot of facilities to change attribute stuff, so there seems to be no other way that creating a new instance of the container. And that might fail in impredictable ways, and that's what it does:
Type check failed in binding to parameter '$the-obj'; expected Any but got Foo (Foo)
at /home/jmerelo/Code/raku/my-raku-examples/frozen.raku:7
Not clear if this is the first the-obj or the second one, but any way, some help is appreciated.

Forbid runtime dependency on package in Nix overlay

Task description
I want to make sure that no derivation I install has no run-time dependency on specified set of derivation. If I ask nix-env to install package that has such run-time dependency, I want it to say that I am asking for impossible. Build-dependencies are fine. I want to avoid huge cascade rebuilds, though.
In other words, I want to make sure that derivation with name = evil never reaches my Nix store, but I am fine that it was used to build other derivations on Hydra. Here is what I tried:
Failed attempt: use derivation meta attribute
self: super: {
evil = super.evil // { meta.broken = True; };
}
but this makes nix-env to refuse install programs that has build-time dependencies on evil, for example it refuses to install go or haskell programs (which are statically linked) because compiler has some transitive dependency on evil.
Failed attempt: replace evil with something harmless
I write overlay that replaces evil:
self: super {
evil = super.harmless; # e.g super.busybox
}
it causes major cascade rebuild.
Random idea
If there is function, like this:
self: super: {
ghc = forget_about_dependencies_but_retain_hash_yes_I_know_what_I_Do [super.evil] super.ghc;
# same for rustc, go and other compilers that link statically.
}
that would be 90% solution for me.
It seems impossible to prevent some derivation from being in store, but it is possible to make sure profile does not contain run-time dependencies:
self: super: {
world = (super.buildEnv {
name = "world";
paths = with super; [ foo bar baz ];
}).overrideAttrs (_: { disallowedRequisites = [ super.evil super.ugly ]; });
}
So, if you put all derivations you want in "world", you can be sure that evil and ugly are not in dependencies. But they will be downloaded into store to build "world", even if they are not actually used by any derivations in paths.

How do I resolve a circular dependency in ES6 modules with a factory function?

I want to write something like this inside my src/core/Chessman.js file:
import King from './chessmen/King'
class Chessman {
static factory(side, quality) {
switch(quality) {
case 'king' : return new King(side) break
// ... other qualities
}
constructor(side) { this.side = side }
cast(position, ref) { }
run(position, startRef, endRef) {}
}
and inside my src/core/chessmen/King.js file:
import Chessman from '../Chessman'
class King extends Chessman {
constructor(side) {
super(side)
this.iterative = false // true for Queens, Rooks and Bishop
this.directions = [
'up', 'up+right', 'right', 'right+down',
'down', 'down+left', 'left', 'left+top'
]
}
// overrides parent behavior
cast(position, ref) {}
run(position, startRef, endRef) {}
}
But sadly I get the error (while testing) with Karma, jasmine and babel
TypeError: Super expression must either be null or a function, not undefined
at src/core/chessmen/King.js:57
And there's no line 57 for the moment in King.js !
You have a circular dependency error. Given what you've shown us, consider the following steps:
Chessman.js starts loading
It pauses execution so its dependencies can load.
King.js starts loading since it is a dependency.
King.js throws because class King extends Chessman runs, but Chessman has not been set yet, because it paused on step #2
You'd be much better off moving your factory function to its own file, to avoid cyclical dependencies. The only safe circular dependencies in JS are ones that are not needed when the module itself is initialized. Since class extends X runs at module initialization time, it is not safe for cycles.
If this was literally your only class, you could write your app such that King.js was imported before Chessman.js, but given your usage of a factory, and your naming scheme, I assume there are other chess pieces. Since every single chess piece class will trigger this issue, there is no way to import them in the correct order. Avoiding the issue by moving the factory function out of Chessman.js is the only solution to this.
If you want to have a factory, instead of saving it directly in the base class module, move it to it's own module - chessman.factory.js. There, do whatever Chessman.factory does in a method or something. This way the chessman.js module wouldn't have to know about modules that need itself,

Elasticsearch / Lucene Misspelled Whitespace

How can I make Elasticsearch correct queries in which keyword should contain whitespace but instead typed adjacent. E.g.
"thisisaquery" -> "this is a query"
my current settings are:
"settings": {
"index": {
"analysis": {
"analyzer": {
"autocomplete": {
"tokenizer": "whitespace",
"filter": [
"lowercase", "engram"
]
}
},
"filter": {
"engram": {
"type": "edgeNGram",
"min_gram": 3,
"max_gram": 10
}
}
}
}
}
There isn't an out of the box tokenizer/token filter to explicitly handle what you're asking for. The closest would be the compound word token filter which requires manually providing a dictionary file which in your case would may require the full english dictionary to work correctly. Even with that it would likely have issues with words that are stems of other words, abbreviations, etc without a lot of additional logic. It may be good enough though depending on your exact requirements.
This ruby project claims to do this. You might try it if you're using ruby, or just look at their code and copy their analyzer settings for it :)
https://github.com/ankane/searchkick