Currying an instance method - exception with modifier 'private'

classic Classic list List threaded Threaded
11 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Currying an instance method - exception with modifier 'private'

Wujek Srujek
Hi. I have the following problem: I have a custom Script subclass, whose all scripts that I evaluate extend (using the CompilerConfiguration setting). The code is this:

abstract class ScriptBase extends Script {

    def __transformations = []

    private __value(transformations) {
        def s = new SomeObject()
        transformations << s
        s
    }

    def value = this.&__value.curry(__transformations) // line 19

    def expand(closure) {
        def transformations = []
        def value = this.&__value.curry(transformations)
        ....
        // value is added to the delegate of the (cloned) closure
        // and any call to value will stash new instances to the transformations variable
    }
}

The idea is this: the __value method creates and stashes away some instances to a transformations list passed as argument. The scripts will not use it, they will use the curried version that uses the instance __tansformations variable. Then, there is another method that takes a closure, and in this closure the value function can be called as well, but this time it must stash the instances to some other list. Hence the currying.

The problem is the code doesn't work - I get:
groovy.lang.GroovyRuntimeException: Failed to create Script instance for class: class Script1. Reason: java.lang.IllegalArgumentException: Can't curry 1 arguments for a closure with 0 parameters.
....
caused by:
Caused by: java.lang.IllegalArgumentException: Can't curry 1 arguments for a closure with 0 parameters.
at org.codehaus.groovy.runtime.CurriedClosure.<init>(CurriedClosure.java:72)
at org.codehaus.groovy.runtime.CurriedClosure.<init>(CurriedClosure.java:86)
at groovy.lang.Closure.curry(Closure.java:527)
        ....
        at groovy.export.ScriptBase.<init>(ScriptBase.groovy:19)

where line 19 is the line where the currying is done, marked above. I completely don't understand the exception, why does it say the closure takes 0 arguments? The __value method takes 2.

When I change the access modifier of the __value method from private to default (public) - it works!

What is going on here?


wujek
Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Jochen Theodorou
Am 28.09.2011 15:08, schrieb Wujek Srujek:

> Hi. I have the following problem: I have a custom Script subclass, whose
> all scripts that I evaluate extend (using the CompilerConfiguration
> setting). The code is this:
>
> abstract class ScriptBase extends Script {
>
>      def __transformations = []
>
>      private __value(transformations) {
>          def s = new SomeObject()
>          transformations << s
>          s
>      }
>
>      def value = this.&__value.curry(__transformations) // line 19
>
>      def expand(closure) {
>          def transformations = []
>          def value = this.&__value.curry(transformations)
>          ....
>          // value is added to the delegate of the (cloned) closure
>          // and any call to value will stash new instances to the
> transformations variable
>      }
> }[...]
> When I change the access modifier of the __value method from private to
> default (public) - it works!

_value is defined in the script you write?

bye blackdrag


--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Wujek Srujek
I am not sure what you mean. the __value method is in the script's base class. I curry it and assign the result to value, and this is what the script invokes (it can also invoke __value, but it will be a hidden feature ;d) So yes, the __value mehod is defined for the script by means of being in the superclass. The script that will eventually be executed defines no methods, it just calls methods like the mentioned value and some others that the base script class provides.

wujek

On Wed, Sep 28, 2011 at 3:43 PM, Jochen Theodorou <[hidden email]> wrote:
Am 28.09.2011 15:08, schrieb Wujek Srujek:
Hi. I have the following problem: I have a custom Script subclass, whose
all scripts that I evaluate extend (using the CompilerConfiguration
setting). The code is this:

abstract class ScriptBase extends Script {

    def __transformations = []

    private __value(transformations) {
        def s = new SomeObject()
        transformations << s
        s
    }

    def value = this.&__value.curry(__transformations) // line 19

    def expand(closure) {
        def transformations = []
        def value = this.&__value.curry(transformations)
        ....
        // value is added to the delegate of the (cloned) closure
        // and any call to value will stash new instances to the
transformations variable
    }
}[...]

When I change the access modifier of the __value method from private to
default (public) - it works!

_value is defined in the script you write?

bye blackdrag


--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Jochen Theodorou
Am 28.09.2011 16:01, schrieb Wujek Srujek:
> I am not sure what you mean. the __value method is in the script's base
> class.

ah sorry, I did misread the code. I thought I did see this.@_value.
this.&_value is a MethodClosure of course. Anyway...

>              private __value(transformations) {
>                  def s = new SomeObject()
>                  transformations << s
>                  s
>              }

the method is private, thus not available in a subclass, so this cannot
work.

bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Wujek Srujek
Yes, the __value method is private, but the value (the curried one) is not, and it will be used. Also, the currying (so reading the method) is done in the base script class body (so pretty much in the constructor), which has access to the method, be it private or not. I wanted to make the __value method private as I don't want the subclasses / scripts to use it, but it doesn't work. It seems strange. Could you please explain why it cannot be read?

wujek

On Wed, Sep 28, 2011 at 5:42 PM, Jochen Theodorou <[hidden email]> wrote:
Am 28.09.2011 16:01, schrieb Wujek Srujek:

I am not sure what you mean. the __value method is in the script's base
class.

ah sorry, I did misread the code. I thought I did see this.@_value. this.&_value is a MethodClosure of course. Anyway...


            private __value(transformations) {
                def s = new SomeObject()
                transformations << s
                s
            }

the method is private, thus not available in a subclass, so this cannot work.


bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Wujek Srujek
Here is some code that can be pased in groovyConsole that shows the problem:

class Base {

    private __value(arg) { println "$arg" } // <<<
    def value = this.&__value.curry('value')
    def extend() {
        def tmp = this.&__value.curry('extend')
        tmp()
    }
}

class Sub extends Base {

    def test() {
        value()
        extend()
    }
}

new Sub().test()


It doesn't work (groovy 

wujek

On Wed, Sep 28, 2011 at 5:52 PM, Wujek Srujek <[hidden email]> wrote:
Yes, the __value method is private, but the value (the curried one) is not, and it will be used. Also, the currying (so reading the method) is done in the base script class body (so pretty much in the constructor), which has access to the method, be it private or not. I wanted to make the __value method private as I don't want the subclasses / scripts to use it, but it doesn't work. It seems strange. Could you please explain why it cannot be read?

wujek


On Wed, Sep 28, 2011 at 5:42 PM, Jochen Theodorou <[hidden email]> wrote:
Am 28.09.2011 16:01, schrieb Wujek Srujek:

I am not sure what you mean. the __value method is in the script's base
class.

ah sorry, I did misread the code. I thought I did see this.@_value. this.&_value is a MethodClosure of course. Anyway...


            private __value(transformations) {
                def s = new SomeObject()
                transformations << s
                s
            }

the method is private, thus not available in a subclass, so this cannot work.


bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email




Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Wujek Srujek
Sorry, I accidently pressed enter and it got sent too early.

class Base {

    private __value(arg) { println "$arg" }
    def value = this.&__value.curry('value')
    def extend() {
        def tmp = this.&__value.curry('extend')
        tmp()
    }
}

class Sub extends Base {

    def test() {
        value()
        extend()
    }
}

new Sub().test()

It doesn't work (groovy 1.8.2). The error I get:

Exception thrown
Sep 28, 2011 6:41:42 PM org.codehaus.groovy.runtime.StackTraceUtils sanitize
WARNING: Sanitizing stacktrace:
java.lang.IllegalArgumentException: Can't curry 1 arguments for a closure with 0 parameters.
at org.codehaus.groovy.runtime.CurriedClosure.<init>(CurriedClosure.java:72)
at org.codehaus.groovy.runtime.CurriedClosure.<init>(CurriedClosure.java:86)
at groovy.lang.Closure.curry(Closure.java:527)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:226)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:64)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at Base.<init>(ConsoleScript7:4)
at Sub.<init>(ConsoleScript7)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:54)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:186)
at ConsoleScript7.run(ConsoleScript7:19)
at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:266)
at groovy.lang.GroovyShell.run(GroovyShell.java:517)
at groovy.lang.GroovyShell.run(GroovyShell.java:172)
at groovy.lang.GroovyShell$run.call(Unknown Source)
at groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy:924)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
at groovy.lang.Closure.call(Closure.java:410)
at groovy.lang.Closure.call(Closure.java:404)
at groovy.lang.Closure.run(Closure.java:488)
at java.lang.Thread.run(Thread.java:662)

java.lang.IllegalArgumentException: Can't curry 1 arguments for a closure with 0 parameters.
at Base.<init>(ConsoleScript7:4)
at Sub.<init>(ConsoleScript7)
at ConsoleScript7.run(ConsoleScript7:19)



The only change it needs is to change the private to def / protected in the line marked with '// <<<'. I think the code should compile and execute fine, unless of course there is something particular about this use case that groovy handles differently.

wujek

 
Here is some code that can be pased in groovyConsole that shows the problem:

class Base {

    private __value(arg) { println "$arg" } // <<<
    def value = this.&__value.curry('value')
    def extend() {
        def tmp = this.&__value.curry('extend')
        tmp()
    }
}

class Sub extends Base {

    def test() {
        value()
        extend()
    }
}

new Sub().test()


It doesn't work (groovy 

wujek

On Wed, Sep 28, 2011 at 5:52 PM, Wujek Srujek <[hidden email]> wrote:
Yes, the __value method is private, but the value (the curried one) is not, and it will be used. Also, the currying (so reading the method) is done in the base script class body (so pretty much in the constructor), which has access to the method, be it private or not. I wanted to make the __value method private as I don't want the subclasses / scripts to use it, but it doesn't work. It seems strange. Could you please explain why it cannot be read?

wujek


On Wed, Sep 28, 2011 at 5:42 PM, Jochen Theodorou <[hidden email]> wrote:
Am 28.09.2011 16:01, schrieb Wujek Srujek:

I am not sure what you mean. the __value method is in the script's base
class.

ah sorry, I did misread the code. I thought I did see this.@_value. this.&_value is a MethodClosure of course. Anyway...


            private __value(transformations) {
                def s = new SomeObject()
                transformations << s
                s
            }

the method is private, thus not available in a subclass, so this cannot work.


bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email





Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Jochen Theodorou
In reply to this post by Wujek Srujek
Am 28.09.2011 17:52, schrieb Wujek Srujek:
> Yes, the __value method is private, but the value (the curried one) is
> not, and it will be used. Also, the currying (so reading the method) is
> done in the base script class body (so pretty much in the constructor),
> which has access to the method, be it private or not. I wanted to make
> the __value method private as I don't want the subclasses / scripts to
> use it, but it doesn't work. It seems strange. Could you please explain
> why it cannot be read?

The MethodClosure is initialized with "this". But "this" is the subclass
instance and if I get the class of "this", I get the subclass, which
does not know anything about private methods in the super class. I see
this actually as bug as it could be done differently. But atm this is
not the case

bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Wujek Srujek
I am not sure if this is a reference of any kind, but Java seems to be doing it 'right'. Consider:

class Base {

private int get() {
return 17;
}

int a = this.get();

public void test() {
System.out.println(a);
}
}

public class Sub extends Base {

public static void main(String[] args) {
new Sub().test();
}
}

It println '17' as expected. Of course, the code does nothing that fancy what the groovy example does. The point is,when Sub is instantiated, the call to the private get() is done in the superclass, who can access it.

If this is a bug, should I file an issue somewhere, or did you already do this?

wujek

On Wed, Sep 28, 2011 at 7:10 PM, Jochen Theodorou <[hidden email]> wrote:
Am 28.09.2011 17:52, schrieb Wujek Srujek:

Yes, the __value method is private, but the value (the curried one) is
not, and it will be used. Also, the currying (so reading the method) is
done in the base script class body (so pretty much in the constructor),
which has access to the method, be it private or not. I wanted to make
the __value method private as I don't want the subclasses / scripts to
use it, but it doesn't work. It seems strange. Could you please explain
why it cannot be read?

The MethodClosure is initialized with "this". But "this" is the subclass instance and if I get the class of "this", I get the subclass, which does not know anything about private methods in the super class. I see this actually as bug as it could be done differently. But atm this is not the case


bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Currying an instance method - exception with modifier 'private'

Jochen Theodorou
Am 28.09.2011 19:25, schrieb Wujek Srujek:
[...]
> If this is a bug, should I file an issue somewhere, or did you already
> do this?

please file a bug

bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


12