Quantcast

changing dynamically the name of classes in a source code

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
25 messages Options
123
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

changing dynamically the name of classes in a source code

frenchy48
Before asking a question I'l have first to explain WHY this question.  

I have been writing a book about programming (for beginners)  

For the labs I use  a small subset of Groovy  
now my labs are slightly boring so I decided to write a small graphical library to facilitate the design of funnier experiments.  

This small library is built around about 20 groovy classes and provides a simple framework to do some graphical programming.  

The people going to use this codes are not english speaking people.  
But it's not a big problem when limiting the use of english to some keywords (for, while, if,...) or a limited number of types such as List or Map.  

But if I introduce more classes it may be a problem.  

So I started thinking about internationalisation of code.  

For my limited number of classes I implemented a "methodMissing" feature that implements a translation of method names.  
it works (though error handling is not perfect and can be confusing)  

Now I was wondering if I could translate the name of this library's classes at runtime.
(there are already languages such as Scratch which are translated in the user's language -including keywords ... but I don't need to go that far-)  

And here are my questions : how to do that and is it worth the trouble?  

I toyed with the idea of using ASTTransformation but I really don't know how to visit my class names and if I can change them at runtime.  
Since the programming features are limited the students are not going to use the constructors of the classes (there are only factories).
So the only places where the class names should be changed is when declaring variables or parameter types.  
(I could sed the source code but I would rather not)  

so is this transformation doable? when? (parsing or semantic?) how? (performance is not an issue and  students program through the groovyconsole)  

(for sure error handling is going to be even more problematic when the user sees a message pertaining to a class which is "under the hood")  

Any advice?  

thanks  
member of Grumpy Old Programmers
OC
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: changing dynamically the name of classes in a source code

OC
Well, I can't resist commenting that a programmer would need English anyway :)

That said, can't you simply sublass? Like

===
class Localizeděščřžýáíí extends LinkedList { }

def ěěě=new Localizeděščřžýáíí()
ěěě<<'Hello'
ěěě<<'note that both class and variable names'
ěěě<<'support accented characters all right'
println "${ěěě.class.simpleName} contains $ěěě"
===

As for variables and argument names, you don't need anything at all for the latter, nothing but 'def' for the former.

All the best,
OC


On 27. 3. 2016, at 17:38, frenchy48 <[hidden email]> wrote:

> Before asking a question I'l have first to explain WHY this question.  
>
> I have been writing a book about programming (for beginners)  
>
> For the labs I use  a small subset of Groovy  
> now my labs are slightly boring so I decided to write a small graphical
> library to facilitate the design of funnier experiments.  
>
> This small library is built around about 20 groovy classes and provides a
> simple framework to do some graphical programming.  
>
> The people going to use this codes are not english speaking people.  
> But it's not a big problem when limiting the use of english to some keywords
> (for, while, if,...) or a limited number of types such as List or Map.  
>
> But if I introduce more classes it may be a problem.  
>
> So I started thinking about internationalisation of code.  
>
> For my limited number of classes I implemented a "methodMissing" feature
> that implements a translation of method names.  
> it works (though error handling is not perfect and can be confusing)  
>
> Now I was wondering if I could translate the name of this library's classes
> at runtime.
> (there are already languages such as Scratch which are translated in the
> user's language -including keywords ... but I don't need to go that far-)  
>
> And here are my questions : how to do that and is it worth the trouble?  
>
> I toyed with the idea of using ASTTransformation but I really don't know how
> to visit my class names and if I can change them at runtime.  
> Since the programming features are limited the students are not going to use
> the constructors of the classes (there are only factories).
> So the only places where the class names should be changed is when declaring
> variables or parameter types.  
> (I could sed the source code but I would rather not)  
>
> so is this transformation doable? when? (parsing or semantic?) how?
> (performance is not an issue and  students program through the
> groovyconsole)  
>
> (for sure error handling is going to be even more problematic when the user
> sees a message pertaining to a class which is "under the hood")  
>
> Any advice?  
>
> thanks  
>
>
>
>
> -----
> member of Grumpy Old Programmers
> --
> View this message in context: http://groovy.329449.n5.nabble.com/changing-dynamically-the-name-of-classes-in-a-source-code-tp5732080.html
> Sent from the Groovy Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: changing dynamically the name of classes in a source code

frenchy48
Ok  students will learn more english later ... but please!
(for instance have a look at Scratch or read this: https://rising.globalvoices.org/blog/2013/03/18/programming-possibilities-writing-code-in-arabic/)


Now subclassing does not work:
my course is using a subset of groovy (my goal is to teach programming not full Groovy)
one of my main message in my course is to have  variables with a type!
so "def x" is not encouraged (not even taught)!
now if you have a factory that returns the proper class and you assign it to a variable typed with a subclass it won't work.
 
SubClassOfSmurf variable = factoryOfSmurf() // won't work no?

member of Grumpy Old Programmers
OC
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: changing dynamically the name of classes in a source code

OC
> one of my main message in my course is to have  variables with a type!
> so "def x" is not encouraged (not even taught)!

Well, that's arguable at best.

Whilst declaring variables is highly _practical_ for it helps to prevent typos and allows both the IDE and compiler to assist the programmer, _conceptually_ it is very wrong. The concept of object programming is that an object is an object is an object; all objects are conceptually equal, and each object can be sent any message (well, the Java howler of “calling methods” instead of the proper paradigm of “sending messages” does not help either :( ).

All in all, given you don't teach Groovy but programming, I would strongly recommend to use some variant of Smalltalk instead -- it is less practical for everyday purposes, but allows the students to grok the principles of OOP _much_ better than anything Java-based ever might.

> now if you have a factory that returns the proper class and you assign it to
> a variable typed with a subclass it won't work.

===
26 /tmp> <w.groovy
class Localizeděščřžýáíí extends LinkedList { }
class Factory { static LinkedList list() { return new LinkedList() } }

Localizeděščřžýáíí ěěě=Factory.list()
ěěě<<"Actually, it does work, though in Java-based language it's a small miracle"
println "${ěěě.class.simpleName} contains $ěěě"
27 /tmp> groovy w
Localizeděščřžýáíí contains [Actually, it does work, though in Java-based language it's a small miracle]
28 /tmp>
===

?

All the best,
OC

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: changing dynamically the name of classes in a source code

frenchy48
Thanks for replying
as a side note OOP appear only in chapter 8 of my book so I have to survive in the meantime
A long long time ago I used object logo ... sticking to groovy helps me to provide the additional codes I want to create simplistic graphics.

now back to the main point:
when I read your example I thought "good Lord I wasn't even aware of that! how come?"
then I tested .... and

---------------
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'scrountch.geom.SFrame[frame1,0,23,300x442,layout=java.awt.BorderLayout,title=,maximized]' with class 'scrountch.geom.SFrame' to class 'Cadre'
--------------
with
class Cadre extends SFrame
(SFrame being a groovy class of the framework)

but
class Smurf extends ArrayList {
}

class Factory {
 static  ArrayList getIt() { return [] ;}
 }
 
 Smurf var = Factory.getIt() ;
does work ....

so ???? what's the difference?

OC wrote
> now if you have a factory that returns the proper class and you assign it to
> a variable typed with a subclass it won't work.

===
26 /tmp> <w.groovy
class Localizeděščřžýáíí extends LinkedList { }
class Factory { static LinkedList list() { return new LinkedList() } }

Localizeděščřžýáíí ěěě=Factory.list()
ěěě<<"Actually, it does work, though in Java-based language it's a small miracle"
println "${ěěě.class.simpleName} contains $ěěě"
27 /tmp> groovy w
Localizeděščřžýáíí contains [Actually, it does work, though in Java-based language it's a small miracle]
28 /tmp>
===
member of Grumpy Old Programmers
OC
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: changing dynamically the name of classes in a source code

OC
Weird... that's probably a question for Jochen on another guru. Perhaps Lists work in a special way, different from other classes? No idea; I just have tested and found it works.

Indeed, with my own class instead of List it leads to the (completely absurd and very anti-object-oriented) “Cannot cast object” exception.

That's precisely the terrible mess which causes Java to be one of the worst languages for learning :(

All the best,
OC


On 28. 3. 2016, at 15:53, frenchy48 <[hidden email]> wrote:

> Thanks for replying
> as a side note OOP appear only in chapter 8 of my book so I have to survive
> in the meantime
> A long long time ago I used object logo ... sticking to groovy helps me to
> provide the additional codes I want to create simplistic graphics.
>
> now back to the main point:
> when I read your example I thought "good Lord I wasn't even aware of that!
> how come?"
> then I tested .... and
>
> ---------------
> org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast
> object
> 'scrountch.geom.SFrame[frame1,0,23,300x442,layout=java.awt.BorderLayout,title=,maximized]'
> with class 'scrountch.geom.SFrame' to class 'Cadre'
> --------------
> with
>
> (SFrame being a groovy class of the framework)
>
> but
>
> does work ....
>
> so ???? what's the difference?
>
>
> OC wrote
>>> now if you have a factory that returns the proper class and you assign it
>>> to
>>> a variable typed with a subclass it won't work.
>>
>> ===
>> 26 /tmp> &lt;w.groovy
>> class Localizeděščřžýáíí extends LinkedList { }
>> class Factory { static LinkedList list() { return new LinkedList() } }
>>
>> Localizeděščřžýáíí ěěě=Factory.list()
>> ěěě&lt;&lt;&quot;Actually, it does work, though in Java-based language
>> it's a small miracle&quot;
>> println &quot;${ěěě.class.simpleName} contains $ěěě&quot;
>> 27 /tmp&gt; groovy w
>> Localizeděščřžýáíí contains [Actually, it does work, though in Java-based
>> language it's a small miracle]
>> 28 /tmp>
>> ===
>
>
>
>
>
> -----
> member of Grumpy Old Programmers
> --
> View this message in context: http://groovy.329449.n5.nabble.com/changing-dynamically-the-name-of-classes-in-a-source-code-tp5732080p5732085.html
> Sent from the Groovy Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: changing dynamically the name of classes in a source code

frenchy48
answer found
Groovy is fantastic!
Since I use the groovyConsole for my teaching scripts
I created a subclass of groovy console
then modified the CompilerConfiguration to accept an importCustomizer that aliases import!
fun!
member of Grumpy Old Programmers
OC
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Proxying how to?!? (was: changing dynamically the name of classes in a source code)

OC
In reply to this post by OC
Incidentally...

On 28. 3. 2016, at 18:10, OC <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Proxying how to?!? (was: changing dynamically the name of classes in a source code)

Winnebeck, Jason
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:[hidden email]]
Sent: Tuesday, March 29, 2016 12:16 PM
To: [hidden email]
Subject: Proxying how to?!? (was: changing dynamically the name of classes in a source code)

Incidentally...

On 28. 3. 2016, at 18:10, OC <[hidden email]> 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.
OC
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Proxying how to?!? (was: changing dynamically the name of classes in a source code)

OC
Jason,

thanks for a quick response!

On 29. 3. 2016, at 19:09, "Winnebeck, Jason" <[hidden email]> wrote:

> You still have to follow the rules of Java bytecode

right, that's why I wrote it's a Java fault (inherited by Groovy), not a Groovy fault.

> that is your class DumbProxy is not related by class hierarchy or interface to AnyClassOfMine, so you can't cast to it.

That is precisely the problem: without casting to it, it can't be used.

> You have to use def/Object type and Groovy's duck typing, or you need to make DumbProxy extend AnyClassOfMine

Far as I understand the Groovy dispatch, this would force me not to go through a relatively clean missingXXX APIs; instead, I would probably have to exploit metaclass functionality directly, or something like that.

Well OK, that I can live with (unless it gets really slow, which it probably would not).

But what if the target class is final? Would never happen with AnyClassOfMine of course, but would happen with 3rd party classes whose instances I might need to proxy.

> or make an interface for them both to implement and use that.

Same problem there: whilst I can turn AnyClassOfMine to implement anything, I can't turn 3rd party classes to do that; and proxying 3rd party classes is essential (after all, with my own classes I can easily use other tricks than proxying to achieve the same result).

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

Correct me please if I am overlooking anything, but it seems to me this is just slightly better implementation of DumbProxy. To redirect methods it uses invokeMethod instead of methodMissing (perhaps it is faster? Dunno. One advantage might be it would technically allow to forward even methods implemented in Proxy itself, but that is prevented by the implementation); but it _does_ share the very same typecasting problem we have just established with my DumbProxy.

Or does it not? If not, how comes?

> http://docs.groovy-lang.org/latest/html/gapi/groovy/util/ProxyGenerator.html

Well this seems really to create an instance of a dynamically made subclass (whoa! But I can see there's nothing else we can do with the bloody Java inherited behaviour), but I must be missing something. That instance does not work as a proxy, but seems to be half-proxy half-real instance of the target class.

Far as I has been able to test, it seems that

pg.instantiateDelegateWithBaseClass([:],[],delegate,class)

(a) creates a new instance of (a private subclas of) given “class” (OK)
(b) which instance gets all the methods (including property getters and setters) “class” contains, directly, without notifying the “delegate” anyhow (COMPLETELY WRONG)
(c) and only properties a methods the “class” does _not_ contain are directed to the delegate (OK)

The functionality needed for proxying differs from that:

(a) the proxied object (a server) exists before a proxy is created;
(b) the delegate (far as I understand what is its purpose?!?) should get _all_ the methods called “of the proxy”...
(c) ... so that it can (pre- or post-process them if need be and) forward them to the real proxied object.

Here's my testing code; perhaps you can point out what's wrong? The documentation is seriously lacking :)

===
class AnyClassOfMine {
  def xxname // renamed from 'name' to be triple sure not to clash with proxy name or something
  def foo(bar) { println "foo of $this called with $bar"; "${bar.toUpperCase()}, I am $xxname" }
}
class Delegate {
  def server
  def propertyMissing(String name) {
    println "- delegate asked for a property '$name' for server $server"
    if (name!='xxname') return 'nonexistent'
    server."$name"
  }
  def propertyMissing(String name,value) {
    println "- delegate asked to set a property '$name' to $value for server $server"
    if (name!='xxname') return 'nonexistent'
    server."$name"
  }
  def methodMissing(String name, args) {
    println "- delegate asked for a method '$name'$args for server $server"
    if (name!='foo') return 'nonexistent'
    server."$name"(*args)
  }
}

def proxied=new AnyClassOfMine(xxname:"Proxied"),delegate=new Delegate(server:proxied)
assert delegate.xxname=='Proxied'

def pg=groovy.util.ProxyGenerator.INSTANCE // is this the proper way to do it?
def proxy=pg.instantiateDelegateWithBaseClass([:],[],delegate,delegate.server.class)
assert proxy instanceof AnyClassOfMine

println "=== Delegate gets unknown method allright:"
println "-> ${proxy.unknown('hello')}"
println "=== Known method implemented by $proxy, instead of being sent through delegate to $proxied!"
println "-> ${proxy.foo('hello')}"
println "=== It should look like this:"
println "-> ${delegate.foo('hello')}"

println "=== Exactly same problem with properties: unknown one correctly forwarded..."
println "-> $proxy.unknownProperty"
println "=== Known property though processed directly by proxy, not forwarded through delegate to $proxied!"
println "-> $proxy.xxname (differs from $proxied.xxname; or read through delegate, $delegate.xxname)"
===

The results are

===
- delegate asked for a property 'xxname' for server AnyClassOfMine@263d0564
=== Delegate gets unknown method allright:
- delegate asked for a method 'unknown'[hello] for server AnyClassOfMine@263d0564
-> nonexistent
=== Known method implemented by Delegate1_groovyProxy@837a151, instead of being sent through delegate to AnyClassOfMine@263d0564!
foo of Delegate1_groovyProxy@837a151 called with hello
-> HELLO, I am null
=== It should look like this:
- delegate asked for a method 'foo'[hello] for server AnyClassOfMine@263d0564
foo of AnyClassOfMine@263d0564 called with hello
-> HELLO, I am Proxied
=== Exactly same problem with properties: unknown one correctly forwarded...
- delegate asked for a property 'unknownProperty' for server AnyClassOfMine@263d0564
-> nonexistent
=== Known property though processed directly by proxy, not forwarded through delegate to AnyClassOfMine@263d0564!
- delegate asked for a property 'xxname' for server AnyClassOfMine@263d0564
-> null (differs from Proxied; or read through delegate, Proxied)
===

Instead, proxy.foo should redirect to the delegate (and through it to server). Similarly, proxy.xxname should get/set the server xxname (through the delegate, again).

> http://docs.groovy-lang.org/latest/html/gapi/groovy/lang/Delegate.html

Again, correct me please if I am overlooking something, but this does not seem to have _anything_ in common with the thing we are solving, i.e., proxying.

Far as I understand, this exploits ASTTs to generate automatically things like

===
class Foo {
  Bar server
  def someBarMethod() { server.someBarMethod() }
  void anotherBarMethod(foo,bar,baz) { server.anotherBarMethod(foo,bar,baz) }
  ....
  // and so forth
}
===

That's rather ugly solution compared with dynamic redirection (though it might be much faster in the Java world, I did not benchmark it, but I can guess this probably will be the point of it; along with the problem that dynamically redirected methods would not work if called from pure Java, which might be enormously important for someone, luckily, completely irrelevant to me :)).

Thanks a lot,
OC


> -----Original Message-----
> From: OC [mailto:[hidden email]]
> Sent: Tuesday, March 29, 2016 12:16 PM
> To: [hidden email]
> Subject: Proxying how to?!? (was: changing dynamically the name of classes in a source code)
>
> Incidentally...
>
> On 28. 3. 2016, at 18:10, OC <[hidden email]> 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.

123
Loading...