To my basic understanding of Stream and sink we add data to sink in order to pass it through the stream but to add it we use a getter instead of setter, which I find counter-intuitive (see example below), could you please explain in simple words why is it how it is and not the other way around?
Example:
class BlogPostViewModel {
StreamController<List<BlogPost>> _blogPostListController = StreamController.broadcast();
Stream<List<BlogPost>> get outBlogPostList => _blogPostListController.stream;
Sink<List<BlogPost>> get _inBlogPostList => _blogPostListController.sink; // Here why use get and not a setter?
}
In advance, thank you.
The getter and setter concept is a way to simulate access to a field in a class but control the behavior of this. So behind the scene there can even not be any variable if we want to e.g. have a getter which fetch some data from somewhere each time (please don't do that).
get and set are therefore methods called when we try to get and set the value of this field:
class MyClass {
void get test => print('You called get');
set test(void input) => print('You called set');
}
void main() {
final obj = MyClass();
obj.test; // You called get
obj.test = null; // You called set
}
So in your case, you want to make so when you try to get the "variable" named _inBlogPostList you will instead get the result of _blogPostListController.sink.
The advantage of this is you get a Sink instance which you can call add and close on. If you don't need to close the sink you can instead use a set method to add stuff into the sink like RĂ©mi Rousselet proposes.
Related
I have a component, that has an #NgOneWay binded attribute message. I have {{cmp.message}} within my html template and it will update automatically when attribute changes. If I want to run a myFunc-function, when cmp.message changes, I can use _scope.watch('message', (newValue, oldValue) => myFunc(), context: this); in my constructor.
Is there a default function, which will fire when my message-attribute changes, like onMessage()?
Or ng-directive, which could be used instead of watch, like ng-onmessage="cmp.myFunc()"?
I think the easiest (and IMHO most beautiful) solution is to implement your cmp.message as getter/setter and execute your function in the setter.
This way you don't need a watch at all.
var _message;
#NgOneWay
get message => _message;
set message(val) {
_message = val;
myFunc();
}
I wish to have the sub-classes of a super-class "registered" by an arbitrary name - whenever I declare a sub-class I wish to also have it entered into the super-class.sub Map.
Is there any way to accomplish this outside of main()?
// base class
class Mineral{
final String formula;
static Map<String,Mineral> sub = {}
Mineral( this.formula );
}
// sub class - declare and register
class Mica extends Mineral{
Mica( String formula ) : super( formula );
}
Mineral.sub['mica'] = Mica; // oops!
when I run this, I get
Error: line 10 pos 1: unexpected token 'Mineral' Mineral.sub['mica'] = Mica;
assuming that executable code is not allowed outside main().
cannot put within the super-class since other sub-classes may declared later, outside the library.
Dart has no way to run code as part of a library being loaded.
Executable code can only be put inside methods, or in field initializers, and static field initializers are lazy so they won't execute any code until you try to read them.
This is done to ensure quick startup - a Dart program doesn't have to execute any code before starting the main library's "main" method.
So, no, there is no way to initialize something that isn't constant before main is called.
Either
Mineral.sub['mica'] = new Mica();
or
static Map<String,Type> sub = {};
When you assign Mica you assign the Type Mica. new Mica() is an instance of Mica that is of the kind Mineral and can be assigned to the map you declared.
edit
Maybe you want to initialize the sub map:
static Map<String,Mineral> sub = {'mica': new Mica()};
hint: the semicolon is missing in this line in your question.
Say I have an instance of a class Foo, and I want to grab a list of all of its methods that are annotated a certain way. I want to have a reference to the method itself, so I'm not looking to use reflection to invoke the method each time, just to grab a reference to it the first time.
In other words, I want to do the reflection equivalent of this:
class Foo {
a() {print("a");}
}
void main() {
var f = new Foo();
var x = f.a; // Need reflective way of doing this
x(); // prints "a"
}
I have tried using InstanceMirror#getField, but methods are not considered fields so that didn't work. Any ideas?
As far as I understand reflection in Dart, there's no way to get the actual method as you wish to. (I'll very happily delete this answer if someone comes along and shows how to do that.)
The best I can come up with to ameliorate some of what you probably don't like about using reflection to invoke the method is this:
import 'dart:mirrors';
class Foo {
a() {print("a");}
}
void main() {
var f = new Foo();
final fMirror = reflect(f);
final aSym = new Symbol('a');
final x = () => fMirror.invoke(aSym, []);
x(); // prints "a"
}
Again, I know that's not quite what you're looking for, but I believe it's as close as you can get.
Side note: getField invokes the getter and returns the result -- it's actually fine if the getter is implemented as a method. It doesn't work for you here, but for a different reason than you thought.
What you're trying to get would be described as the "closurized" version of the method. That is, you want to get the method as a function, where the receiver is implicit in the function invocation. There isn't a way to get that from the mirror. You could get a methodMirror as
reflect(foo).type.methods[const Symbol("a")]
but you can't invoke the result.
void main() {
A one = new A(1);
A two = new A(2);
var fnRef = one.getMyId; //A closure created here
var anotherFnRef = two.getMyId; //Another closure created here
}
class A{
int _id;
A(this._id);
int getMyId(){
return _id;
}
}
According to the dart language tour page referencing methods like this creates a new closure each time. Does anyone know why it does this? I can understand creating closures when defining a method body as we can use variables in an outer scope within the method body, but when just referencing a method like above, why create the closure as the method body isn't changing so it can't use any of the variables available in that scope can it? I noticed in a previous question I asked that referencing methods like this effectively binds them to the object they were referenced from. So in the above example if we call fnRef() it will behave like one.getMyId() so is the closure used just for binding the calling context? ... I'm confused :S
UPDATE
In response to Ladicek. So does that mean that:
void main(){
var fnRef = useLotsOfMemory();
//did the closure created in the return statement close on just 'aVeryLargeObj'
//or did it close on all of the 'veryLargeObjects' thus keeping them all in memory
//at this point where they aren't needed
}
useLotsOfMemory(){
//create lots of 'veryLarge' objects
return aVeryLargeObj.doStuff;
}
Ladicek is right: accessing a method as a getter will automatically bind the method.
In response to the updated question:
No. It shouldn't keep the scope alive. Binding closures are normally implemented as if you invoked a getter of the same name:
class A{
int _id;
A(this._id);
int getMyId() => _id;
// The implicit getter for getMyId. This is not valid
// code but explains how dart2js implements it. The VM has
// probably a similar mechanism.
Function get getMyId { return () => this.getMyId(); }
}
When implemented this way you will not capture any variable that is alive in your useLotsOfMemory function.
Even if it really was allocating the closure inside the useLotsOfMemory function, it wouldn't be clear if it kept lots of memory alive.
Dart does not specify how much (or how little) is captured when a closure is created. Clearly it needs to capture at least the free variables of itself. This is the minimum. The question is thus: "how much more does it capture"?
The general consensus seems to be to capture every variable that is free in some closure. All local variables that are captured by some closure are moved into a context object and every closure that is created will just store a link to that object.
Example:
foo() {
var x = new List(1000);
var y = new List(100);
var z = new List(10);
var f = () => y; // y is free here.
// The variables y and z are free in some closure.
// The returned closure will keep both alive.
// The local x will be garbage collected.
return () => z; // z is free here.
}
I have seen Scheme implementations that only captured their own free variables (splitting the context object into independent pieces), so less is possible. However in Dart this is not a requirement and I wouldn't rely on it. For safety I would always assume that all captured variables (independent of who captures them) are kept alive. I would also make the assumption that bound closures are implemented similar to what I showed above and that they keep a strict minimum of memory alive.
That's exactly right -- the closure captures the object on which the method will be invoked.
I want to do this in Actionscript:
typeof(control1) != typeof(control2)
to test if two objects are of the same type. This would work just fine in C#, but in Actionscript it doesnt. In fact it returns 'object' for both typeof() expressions because thats the way Actionscript works.
I couldn't seem to find an alternative by looking in the debugger, or on pages that describe typeof() in Actionscript.
Is there a way to get the actual runtime type?
The best way is to use flash.utils.getQualifiedClassName(). Additionally, you can use flash.utils.describeType() to get an XML document the describes more about the class.
Actionscript 3 has an is operator which can be used to compare objects. Consider the following code:
var mySprite:Sprite = new Sprite();
var myMovie:MovieClip = new MovieClip();
trace(mySprite is Sprite);
trace(myMovie is MovieClip);
trace(mySprite is MovieClip);
trace(myMovie is Sprite);
Which will produce the following output:
true
true
false
false
This will work for built-in classes, and classes you create yourself. The actionscript 2 equivalent of the is operator is instanceof.
You'll want to use the Object.prototype.constructor.
From the documentation:
dynamic class A {}
trace(A.prototype.constructor); // [class A]
trace(A.prototype.constructor == A); // true
var myA:A = new A();
trace(myA.constructor == A); // true
(Conveniently, this is also how to check types in javascript, which is what originally led me to this in the docs)
So, to test this out before I posted here, I tried it in an app I have, in a class called Player. Since the prototype property is static, you can't call it using "this" but you can just skip the scope identifier and it works:
public function checkType():void {
trace(prototype.constructor, prototype.constructor == Player);
// shows [class Player] true
}
Is there a way to get the actual runtime type?
Yes.
var actualRuntimeType:Class = Object(yourInstance).constructor;
Some other answers already refer to .constructor, but you can't always directly access .constructor in ActionScript 3. It is only accessible on dynamic classes, which most classes are not. Attempting to use it on a regular class will cause a compile-time error under the default settings.
However, because every class inherits from Object, which is dynamic, we can look up their .constructor property just by casting an instance to Object.
Therefore if we are not interested in subclasses, we can confirm that two instances are of exactly the same class by simply evaluating this:
Object(instanceA).constructor === Object(instanceB).constructor;
I learned of this from the post "Get the class used to create an object instance in AS3" by Josh Tynjala.
A even simpler alternative that also works for me is just:
var actualRuntimeType:Class = yourInstance["constructor"];
The runtime is entirely capable of giving you the .constructor, it's just that the compiler complains if you use that syntax. Using ["constructor"] should produce the same bytecode, but the compiler isn't clever enough to stop you.
I included this second because it hasn't been tested anywhere except my current Flash environment, whereas several users have said that the method described above works for them.
If you want to account for inheritance, then you might want to try something like this:
if (objectA is objectB.constructor || objectB is objectA.constructor)
{
// ObjectA inherits from ObjectB or vice versa
}
More generally, if you want to test whether objectA is a subtype of objectB
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
...
if (objectA is getDefinitionByName(getQualifiedClassName(objectB)))
{
...
}
Object obj = new Object();
Object o = new Object();
if(o.getClass().getName().endsWith(obj.getClass().getName())){
return true;
}else{
return false;
}