scala - how to use applyDynamic on Any objects -
i'm considering using new type dynamic, find obvious use case not implemented. i'm trying create convenience wrappers object-oriented database. suffers casting , usablity issues, because serializes , deserializes objects (it's methods return object).
first question: method of database deserializes object of type a. althought has method a() , may know @ given moment, have a, can't call a(), since java sees object. dynamic mechanism try me if "underlying" object has method, or have deal in applydynamic myself? tried out in repl, doesn't seem me. if have check myself, easiest way (using scala's new reflection or not), check if object has method "methodname" , if yes invoke it.
scared off https://stackoverflow.com/a/11056410/703862 fall java's reflection, method invocation part quite easily.
i come this:
scala> import java.lang.reflect.method import java.lang.reflect.method scala> class dyntest3 extends dynamic { | def pee():string = "yuppie" | def execsucced(method: method, args: any*):boolean = return try{method.invoke(args); true} catch { case e: exception => false } | def applydynamic(methodname : string)(args: any*){ | val succed = classof[dyntest3].getdeclaredmethods.filter(m => m.getname() == methodname).exists(m => execsucced(m)) | if (!succed) | throw new java.lang.nosuchmethodexception | } | } defined class dyntest3
but:
scala> val y: object = new dyntest3 y: object = dyntest3@74c74b55 scala> y.asinstanceof[dynamic].pee() <console>:11: error: value applydynamic not member of dynamic y.asinstanceof[dynamic].pee()
so basically, doesn't work, if cast dynamic. casting dynamic make whole thing useless, since want save user casting. maybe 1 create implicit conversion any2dynamic...
any hints?
dynamic
in scala simple compile-time rewriting scheme. details provided in sip-17: type dynamic, , here try explain them in different words.
unlike in c#, dynamic
introduces entire infrastructure of metaobjects, binders , callsite caching + implements mini-c# compiler services overloading during runtime, in scala decided go simplest thing possible.
i've mentioned compile-time rewriting, it's time elaborate. there several rules, let's take @ important one.
if cannot compile foo.bar(arg1 ... argn), , foo has static type subtype of dynamic, rewrite invocation foo.applydynamic("bar")(arg1 .. argn). rewritten expression typechecked usual, if written manually programmer.
in case of y.asinstanceof[dynamic].pee()
, receiver of call, y.asinstanceof[dynamic], of static type subtypes dynamic, rewriting triggered. result of rewriting y.asinstanceof[dynamic].applydynamic("pee")()
. however, when scala tries typecheck expression, fails, because dynamic empty marker trait, doesn't define methods.
to solve problem, cast subtypes dynamic , has applydynamic member (or not cast, make api return not object, something). can either write or use dynamicproxy (subclassed incorporate custom logic), hope included in 2.10.0-m5.
Comments
Post a Comment