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 bound o. 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) followed unregister(o.foo) not work, because each o.foo different. can see trying print(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

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -