Confusing Scala Dynamic code snippet -
i came across following code snippet on scala mailing list:
scala> class dynamicimpl(x: anyref) extends dynamic {      |   def _select_(name: string): dynamicimpl = {      |     new dynamicimpl(x.getclass.getmethod(name).invoke(x))      |   }      |   def _invoke_(name: string)(args: any*) = {      |     new dynamicimpl(x.getclass.getmethod(name, args.map(_.asinstanceof[anyref].getclass) : _*).invoke(x, args.map(_.asinstanceof[anyref]) : _*))      |   }      |   override def typed[t] = x.asinstanceof[t]      |   override def tostring = "dynamic(" + x.tostring + ")"      | } defined class dynamicimpl  scala>   scala> implicit def todynamic(x: any): dynamic = new dynamicimpl(x.asinstanceof[anyref]) todynamic: (x: any)dynamic  scala> class duck {      |   def quack = "quack!"      | } defined class duck  scala> class quackingswan {      |   def quack = "swack!"      | } defined class quackingswan  scala> def makequack(d: dynamic) {      |   println(d.quack.typed[string])      | } dynatype: d._select_("quack") makequack: (d: dynamic)unit  scala> makequack(new duck) quack!  scala> makequack(new quackingswan) swack!  scala> val s: dynamic = "hello, world!" s: dynamic = dynamic(hello, world!)  scala> s.tolowercase dynatype: line8$object.$iw.$iw.s._select_("tolowercase") res2: dynamic = dynamic(hello, world!)  scala> s.length dynatype: line8$object.$iw.$iw.s._select_("length") res3: dynamic = dynamic(13)  scala> s.isempty.typed[boolean] dynatype: line8$object.$iw.$iw.s._select_("isempty") res4: boolean = false   what's _select_ , _invoke_ here?
_select_ , _invoke_ behave ruby missing_method. when method called on dynamic instance not implement method, _select_ or _invoke_ called instead. 2 methods can implemented wish.
in example, use reflection call actual implementation of x member. instance:
scala> val s: dynamic = "hello, world!" s: dynamic = dynamic(hello, world!)  scala> s.tolowercase dynatype: line8$object.$iw.$iw.s._select_("tolowercase") res2: dynamic = dynamic(hello, world!)   the method tolowercase not defined in s. method _select_ called instead argument "tolowercase". dynamic mechanism call x.tolowercase using reflection , wrap result in new dynamic instance.
_select_ called method without arguments, while _invoke_ called method arguments.
Comments
Post a Comment