scope - dart method calling context -
i used below see how dart calls methods passed in other methods see context passed in method would/can called under.
void main() { var 1 = new idable(1); var 2 = new idable(2); print('one ${caller(one.getmyid)}'); //one 1 print('two ${caller(two.getmyid)}'); //two 2 print('one ${callerjustforthree(one.getmyid)}'); //nosuchmethod exception } class idable{ int id; idable(this.id); int getmyid(){ return id; } } caller(fn){ return fn(); } callerjustforthree(fn){ var 3 = new idable(3); three.fn(); }
so how caller
manager call argument fn
without context i.e. one.fn()
, , why callerjustforthree
fail call passed in fn
on object has function defined it?
in dart there difference between instance-method, declared part of class, , other functions (like closures , static functions).
instance methods ones (except constructors) can access this
. conceptually part of class description , not object. is, when method call o.foo()
dart first extracts class-type of o
. searches foo
in class description (recursively going through super classes, if necessary). applies found method this
set o
.
in addition being able invoke methods on objects (o.foo()
) possible bound closure: o.foo
(without parenthesis invocation). however, , crucial, form syntactic sugar (<args>) => o.foo(<args>)
. is, creates fresh closure captures o
, redirects calls instance method.
this whole setup has several important consequences:
you can tear off instance methods , bound closure. result of
o.foo
automatically boundo
. no need bind (but no way bind different instance). way, in example,one.getmyid
works. getting following closure:() => one.getmyid()
instead.it not possible add or remove methods objects. need change class description , (intentionally) not supported.
var f = o.foo;
implies fresh closure time. means cannot use bound closure key in hashtable. example,register(o.foo)
followedunregister(o.foo)
not work, because each o.foo different. can see tryingprint(o.foo == o.foo)
.you cannot transfer methods 1 object another. try access instance methods, bound.
looking @ examples:
print('one ${caller(one.getmyid)}'); //one 1 print('two ${caller(two.getmyid)}'); //two 2 print('one ${callerjustforthree(one.getmyid)}'); //nosuchmethod exception
these lines equivalent to:
print('one ${caller(() => one.getmyid())}'); print('two ${caller(() => two.getmyid())}'); print('one ${callerjustforthree(() => one.getmyid())}';
inside callerjustforthree
:
callerjustforthree(fn){ var 3 = new idable(3); three.fn(); }
the given argument fn
ignored. when doing three.fn()
in last line dart find class description of three
(which idable
) , search fn
in it. since doesn't find 1 call nosuchmethod
fallback. fn
argument ignored.
if want call instance member depending on argument rewrite last example follows:
main() { ... callerjustforthree((o) => o.getmyid()); } callerjustforthree(invokeidablemember){ var 3 = new idable(3); invokeidablemember(three); }
Comments
Post a Comment