groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Winnebeck, Jason" <Jason.Winneb...@windstream.com>
Subject RE: Proxying how to?!? (was: changing dynamically the name of classes in a source code)
Date Tue, 29 Mar 2016 17:09:56 GMT
You still have to follow the rules of Java bytecode, that is your class DumbProxy is not related
by class hierarchy or interface to AnyClassOfMine, so you can't cast to it. You have to use
def/Object type and Groovy's duck typing, or you need to make DumbProxy extend AnyClassOfMine
or make an interface for them both to implement and use that.

Other options to consider include:
http://docs.groovy-lang.org/latest/html/gapi/groovy/util/Proxy.html
http://docs.groovy-lang.org/latest/html/gapi/groovy/util/ProxyGenerator.html
http://docs.groovy-lang.org/latest/html/gapi/groovy/lang/Delegate.html

Jason

-----Original Message-----
From: OC [mailto:ocs@ocs.cz] 
Sent: Tuesday, March 29, 2016 12:16 PM
To: users@groovy.apache.org
Subject: Proxying how to?!? (was: changing dynamically the name of classes in a source code)

Incidentally...

On 28. 3. 2016, at 18:10, OC <ocs@ocs.cz> wrote:
> completely absurd and very anti-object-oriented) "Cannot cast object" exception.

... this reminded me of a problem I so far haven't been able to find a proper solution for:
how the heck do you proxy in Groovy?

In ObjC, I can write

===
@interface AnyClassOfMine:Beanlike
@property NSString *name;
@end
@implementation AnyClassOfMine @end

@interface DumbProxy:Beanlike
@property id server;
@end
@implementation DumbProxy
-forwardingTargetForSelector:(SEL)sel { return self.server; }
@end

id objects=@[[AnyClassOfMine new:@"name":@"Direct"],[DumbProxy new:@"server":[AnyClassOfMine
new:@"name":@"Proxied"]]];
for (AnyClassOfMine *o in objects) NSLog(@"got %@",o.name);
===

and it works precisely as assumed, writing out

===
2016-03-29 17:57:37.501 a.out[5387:707] got Direct
2016-03-29 17:57:37.503 a.out[5387:707] got Proxied
===

(Note if interested: the Beanlike superclass is irrelevant, it just simulates the new Foo(bar:bax)
functionality of Groovy, which ObjC does not have, by implementing the new:(property-name):(value)
method.)

Groovy -- unlike pure Java -- is smart enough to allow me to _implement_ such a proxy, but
for sweet world, I cannot find a way to _use_ it?

===
class AnyClassOfMine {
  def name
}

class DumbProxy {
  def server
  def propertyMissing(String name) {
    server."$name"
  }
}

def objects=[new AnyClassOfMine(name:"Direct"),new DumbProxy(server:new AnyClassOfMine(name:"Proxied"))]
for (AnyClassOfMine o in objects) println "got $o.name"
===

Alas, instead of working as expected, this fails with the aforementioned nonsensical exception:

===
got Direct
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'DumbProxy@73f43791'
with class 'DumbProxy' to class 'AnyClassOfMine'
...
===

How do you write and use a proxy in Groovy, so that it works properly?

(Note: "for (o in objects) ..." would work is this case, but would bring other problems, e.g.,
if there was a method "foo(AnyClassOfMine obj)" called as "for (o in objects) foo(o)", it
would cause "No signature of method is applicable for argument types: (DumbProxy)".)

Thanks a lot,
OC

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended recipient(s).
Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the
intended recipient, please contact the sender by reply email and destroy all copies of the
original message and any attachments.

Mime
View raw message