This is based on this functional demo.
I'm seeing that unnamed modules are imported by SystemJS 0.21.4 as empty objects.
// define('a', [], function () { return 'A'; });
SystemJS.import('a.js')
.then(m => console.log(m.default, '<- a')) // "A"
// define('b', [], function () { return 'B'; });
SystemJS.import('b.js')
.then(m => console.log(m.default, '<- b')) // {}
// define([], function () { return 'A'; });
SystemJS.import('a-anon.js')
.then(m => console.log(m.default, '<- a-anon')) // "A"
// define([], function () { return 'B'; });
SystemJS.import('b-anon.js')
.then(m => console.log(m.default, '<- b-anon')) // "B"
For some reason, a.js imports correctly as "A", but b.js imports as an empty object (instead of "B"). If I reorder them so that b.js is imported first, I see the opposite--b imports correctly and a does not.
What's going on here? Is this a bug? Am I using SystemJS/AMD incorrectly?
Cross-posted from Github
The problem here is the first argument, the "id", which must be top-level:
The first argument, id, is a string literal. It specifies the id of the module being defined. This argument is optional, and if it is not present, the module id should default to the id of the module that the loader was requesting for the given response script. When present, the module id MUST be a "top-level" or absolute id (relative ids are not allowed).
More details on the AMD-page on github.
In the case of B just the object of the module is returned. Module here is the function in which the definition is made.
There are still one interesting point, even it might not be too surprising:
If the 2nd URL is loaded first (b.js) even if the sorting in the script is a.js, b.js, then B is also the assigned Symbol. That means the first transferred definition-file wins. You can test it by loading one file from cdn, the other one local.
Furthermore, if you assign C and D in the same kind like A and B, then also the objects get shown. So the behavior is the same like with B.
Like you've shown with your two last examples the problem never occurs, when the id as optional parameter is omitted.
Related
I am spying on method emit of EventEmitter in Angular
spyOn(answerComponent.answerEmitter, 'emit');
I want to check that emit was called with an argument A but I don't want to check exact match with A. I want to check that emit was called with values A.a, A.b and ignore value of A.c.
Is it possible to do so?
Use jasmine.objectContaining.
const emit = spyOn(answerComponent.answerEmitter, 'emit');
expect(emit).toHaveBeenCalledWith(jasmine.objectContaining({ a: <value>, b: <value>));
Two ways come to my mind:
One by using the native toHaveBeenCalledWith
expect(answerComponent.answerEmitter, 'emit').toHaveBeenCalledWith(A.a);
expect(answerComponent.answerEmitter, 'emit').toHaveBeenCalledWith(A.b);
// you can think of all the callers being tracked as an array and you can assert with
// toHaveBeenCalledWith to check the array of all of the calls and see the arguments
expect(anserComponent.anserEmitter, 'emit').not.toHaveBeenCalledWith(A.c); // maybe you're looking for this as well
You can also spy on the emit and call a fake function:
spyOn(answerComponent.answerEmitter, 'emit').and.callFake((arg: any) => {
// every time emit is called, this fake function is called
if (arg !== A.a || arg !== A.b) {
throw 'Wrong argument passed!!'; // you can refine this call fake
} // but the point is that you can have a handle on the argument passed and assert it
});
Consider this code to extend the Object type:
interface Object
{
doSomething() : void;
}
Object.prototype.doSomething = function ()
{
//do something
}
With this in place, the following both compile:
(this as Object).doSomething();
this.doSomething();
BUT: when I'm typing the first line, Intellisense knows about the doSomething method and shows it in the auto-completion list. When I'm typing the second line, it does not.
I'm puzzled about this, because doesn't every variable derive from Object, and therefore why doesn't Visual Studio show the extra method in the method list?
Update:
Even though the Intellisense doesn't offer the method, it does seem to recognize it when I've typed it manually:
What could explain that?!
...because doesn't every variable derive from Object
No, for two reasons:
1. JavaScript (and TypeScript) has both objects and primitives. this can hold any value (in strict mode), and consequently can be a primitive:
"use strict";
foo();
foo.call(42);
function foo() {
console.log(typeof this);
}
Here's that same code in the TypeScript playground. In both cases (here and there), the above outputs:
undefined
number
...neither of which is derived from Object.
2. Not all objects inherit from Object.prototype:
var obj = Object.create(null);
console.log(typeof obj.toString); // undefined
console.log("toString" in obj); // false
If an object's prototype chain is rooted in an object that doesn't have a prototype at all (like obj above), it won't have the features of Object.prototype.
From your comment below:
I thought even primitives like number inherit from Object. If number doesn't, how does number.ToString() work?
Primitives are primitives, which don't inherit from Object. But you're right that most of them seem to, because number, string, boolean, and symbol have object counterparts (Number, String, Boolean, and Symbol) which do derive from Object. But not all primitives do: undefined and null throw a TypeError if you try to treat them like objects. (Yes, null is a primitive even though typeof null is "object".)
For the four of them that have object counterparts, when you use a primitive like an object like this:
var a = 42;
console.log(a.toString());
...an appropriate type of object is created and initialized from the primitive via the abstract ToObject operation in the spec, and the resulting object's method is called; then unless that method returns that object reference (I don't think any built-in method does, but you can add one that does), the temporary object is immediately eligible for garbage collection. (Naturally, JavaScript engines optimize this process in common cases like toString and valueOf.)
You can tell the object is temporary by doing something like this:
var a = 42;
console.log(a); // 42
console.log(typeof a); // "number"
a.foo = "bar"; // temp object created and released
console.log(a.foo); // undefined, the object wasn't assigned back to `a`
var b = new Number(42);
console.log(b); // (See below)
console.log(typeof b); // "object"
b.foo = "bar"; // since `b` refers to an object, the property...
console.log(b.foo); // ... is retained: "bar"
(Re "see below": In the Stack Snippets console, you see {} there; in Chrome's real console, what you see depends on whether you have the console open: If you don't, opening it later will show you 42; if you do, you'll see ▶ Number {[[PrimitiveValue]]: 42} which you can expand with the ▶.)
Does number implement its own toString method, having nothing to do with Object?
Yes, but that doesn't really matter re your point about primitives and their odd relationship with Object.
So to round up:
this may contain a primitive, and while some primitives can be treated like objects, not all can.
this may contain an object reference for an object that doesn't derive from Object (which is to say, doesn't have Object.prototype in its prototype chain).
JavaScript is a hard language for IntelliSense. :-)
I currently have two macros that are part of a (very limited-audience) plugin I'm developing, that both look basically like:
(function(){
exports.name = "name";
exports.params = [
{name: "value"}
];
function get(tiddler) {
// return some contents of some tiddler fields according to some rule
}
function parse(data) {
// convert string to some kind of useful object
}
function logic(x, y) {
// determine whether the two objects correspond in some way
};
function format(data, title) {
// produce WikiText for a link with some additional decoration
};
exports.run = function(value) {
value = parse(value);
var result = [];
this.wiki.each(function(tiddler, title) {
var data = get(tiddler);
if (data !== undefined && logic(value, parse(data))) {
result.push(format(data, title));
}
});
return result.join(" | ");
};
})();
So they're already fairly neatly factored when considered individually; the problem is that only the core logic is really different between the two macros. How can I share the functions get, logic and format between the macros? I tried just putting them in a separate tiddler, but that doesn't work; when the macros run, TW raises an error claiming that the functions are "not defined". Wrapping each function as its own javascript macro in a separate tiddler, e.g.
(function(){
exports.name = "get";
exports.params = [
{name: "tiddler"}
];
exports.run = function(tiddler) {
// return some contents of some tiddler fields according to some rule
}
})();
also didn't help.
I'd also like to set this up to be more modular/flexible, by turning the main get/parse/logic/format process into a custom filter, then letting a normal filter expression take care of the iteration and using e.g. the widget or <> macro to display the items. How exactly do I set this up? The documentation tells me
If the provided filter operators are not enough, a developer can add
new filters by adding a module with the filteroperator type
but I can't find any documentation of the API for this, nor any examples.
How can I share the functions get, logic and format between the macros?
You can use the Common/JS standard require('<tiddler title>') syntax to access the exports of another tiddler. The target tiddler should be set up as a JS module (ie, the type field set to application/javascript and the module-type field set to library). You can see an example here:
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/modules/widgets/count.js#L15
I'd also like to set this up to be more modular/flexible, by turning the main get/parse/logic/format process into a custom filter, then letting a normal filter expression take care of the iteration and using e.g. the widget or <> macro to display the items. How exactly do I set this up?
The API for writing filter operators isn't currently documented, but there are many examples to look at:
https://github.com/Jermolene/TiddlyWiki5/tree/master/core/modules/filters
I'm learning Dart and see the following idiom a lot:
someFuture.then((_) => someFunc());
I have also seen code like:
someOtherFuture.then(() => someOtherFunc());
Is there a functional difference between these two examples?
A.k.a., What does passing _ as a parameter to a Dart function do?
This is particularly confusing given Dart's use of _ as a prefix for declaring private functions.
It's a variable named _ typically because you plan to not use it and throw it away. For example you can use the name x or foo instead.
The difference between (_) and () is simple in that one function takes an argument and the other doesn't.
DON’T use a leading underscore for identifiers that aren’t private.
Exception: An unused parameter can be named _, __, ___, etc. This
happens in things like callbacks where you are passed a value but you
don’t need to use it. Giving it a name that consists solely of
underscores is the idiomatic way to indicate the value isn’t used.
https://dart.dev/guides/language/effective-dart/style
An underscore (_) is usually an indication that you will not be using this parameter within the block. This is just a neat way to write code.
Let's say I've a method with two parameters useful and useless and I'm not using useless in the code block:
void method(int useful, int useless) {
print(useful);
}
Since useless variable won't be used, I should rather write the above code as:
void method(int useful, int _) { // 'useless' is replaced with '_'
print(useful);
}
From the Dart Doc - PREFER using _, __, etc. for unused callback parameters.
Sometimes the type signature of a callback function requires a
parameter, but the callback implementation doesn't use the
parameter. In this case, it's idiomatic to name the unused parameter
_. If the function has multiple unused parameters, use additional
underscores to avoid name collisions: __, ___, etc.
futureOfVoid.then((_) {
print('Operation complete.');
});
This guideline is only for functions that are both anonymous and
local. These functions are usually used immediately in a context
where it's clear what the unused parameter represents. In contrast,
top-level functions and method declarations don't have that context,
so their parameters must be named so that it's clear what each
parameter is for, even if it isn't used.
Copy paste the following code in DartPad and hit Run -
void main() {
Future.delayed(Duration(seconds: 1), () {
print("No argument Anonymous function");
});
funcReturnsInteger().then((_) {
print("Single argument Anonymous function " +
"stating not interested in using argument " +
"but can be accessed like this -> $_");
});
}
Future<int> funcReturnsInteger() async {
return 100;
}
That expression is similar to "callbacks" in node.js, the expression have relation to async task.
First remember that => expr expression is shorthand for {return *expr*}, now in someFuture.then((_) => someFunc()), someFuture is a variable of type Future, and this keeps your async task, with the .then method you tell what to do with your async task (once completed), and args in this method you put the callback ((response) => doSomethingWith(response)).
You learn more at Future-Based APIs and Functions in Dart. Thanks
Very common use, is when we need to push a new route with Navigator but the context variable in the builder is not going to be used:
// context is going to be used
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => NewPage(),
));
// context is NOT going to be used
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => NewPage(),
));
I think what people are confusing here is that many think the _ in
someFuture.then((_) => someFunc());
is a parameter provided to the callback function which is wrong, its actually a parameter passed back from the function that you can give a name that you want (except reserved keywords of course), in this case its an underscore to show that the parameter will not be used. otherwise, you could do something like in example given above:((response) => doSomethingWith(response))
I'm trying to update my code but I'm stuck at this codeline.
How do I proceed to convert this to preg_replace_callback?
$buffer = preg_replace("#§([a-z0-9-_]+)\.?([a-z0-9-_]+)?#ie","\$templ->\\1(\\2)",$buffer);
Here is the process of converting preg_replace (with the e modifier) to preg_replace_callback. You create a function that will act on all of the matches that it finds. Normally this is pretty simple, however with your case it is a little more complex as the function returns the value of an object. To accommodate this, you can use an anonymous function (a function without a name) and attach the USE keyword with your object to it. This can be done inline, however for the sake of clarity, I have made it its own variable.
Take a look at this portion of the complete code below:
$callback_function = function($m) use ($templ) {
I created a variable named callback_function that will be used in the preg_replace_callback function. This function will be fed each match as the variable $m automatically. So within the function you can use $m[1] and $m[2] to access the parts of the expression that it matched. Also note that I've attached the $templ variable with the USE keyword so that $templ will be available within the function.
Hopefully that makes sense. Anyway, here is the complete code:
<?php
// SET THE TEXT OF THE BUFFER STRING
$buffer = 'There are a bunch of §guns.roses growing along the side of the §guns.road.';
// THIS IS JUST A SAMPLE CLASS SINCE I DO NOT KNOW WHAT YOUR CLASS REALLY LOOKS LIKE
class Test {
// FUNCTION NAMED 'guns' WITH A SPACE FOR A PARAMETER
public function guns($info) {
return '<b>BLUE '.strtoupper($info).'</b>';
}
}
// INSTANTIATE A NEW 'Test' CLASS
$templ = new Test();
// THIS IS THE FUNCTION THAT YOUR CALLBACK WILL USE
// NOTICE THAT IT IS AN ANONYMOUS FUNCTION (THERE IS NO FUNCTION NAME)
$callback_function = function($m) use ($templ) {
return $templ->$m[1]($m[2]);
};
// THIS USES PREG_REPLACE_CALLBACK TO SUBSTITUTE OUT THE MATCHED TEXT WITH THE CALLBACK FUNCTION
$buffer = preg_replace_callback('/§([a-z0-9-_]+)\.?([a-z0-9-_]+)?/i', $callback_function, $buffer);
// PRINT OUT THE FINAL VERSION OF THE STRING
print $buffer;
This outputs the following:
There are a bunch of <b>BLUE ROSES</b> growing along the side of the <b>BLUE ROAD</b>.