Quantcast

Re: withFormat is blind when I am def

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: withFormat is blind when I am def

Erik  Pragt
Hi Virtualeyes,

I think if you're just doing to do a println, a System.out.println would work. Haven't tested it though!

Erik

On Aug 21, 2011, at 12:32 AM, virtualeyes wrote:

> def save() {
> def entity = new Node(params) // entity is def'd, so local scope
> if(entity.save(flush:true)) {
> withFormat {
> println entity // works, toString() invoked
> html {
> println entity // error, java.lang.NoSuchMethodError (at withFormat &
> html lines)
> }
> }
> }
> }
>
> the only way to get things working is to create an instance level variable
> and this.foo it; otherwise nested withFormat closure has no knowledge of
> outer scope. This may be old hat Groovy for some, but was a bit of a
> surprise for me. Is there a way around this? I'd prefer not to have to work
> outside the nested closure if possible.
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/withFormat-is-blind-when-I-am-def-tp3757733p3757733.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind to def instance

virtualeyes
Need more than println, that's just to show the issue.

Basically one needs to refer to an instance variable inside of nested closures -- minor hassle, but obviously work aroundable.

Interestingly, experimenting I tried:
html { obj->println obj }(entity)

invoking the closure immediately; it works, but the caveat is that actually it does not, since after your invoking of the closure, grails follows, calling html {} without args ;-(

Would be nice to pass args to nested withFormat closures; then you wouldn't be forced assign instance variable(s)
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: withFormat is blind when I am def

Johannes Neugschwentner
In reply to this post by Erik Pragt
hey Virtualeyes!

just a blind guess as I won't test it now:
Is it possible grails is expecting _only_ HTML in a withFormat html() block ...
so it doesn't know of any println ?

anyway it says missingMethodException not MissingPropertyException so it's not about entity but println

try html { [node:entity] } and access the var "node" in your gsp

cheers, Joehannes

2011/8/21 Erik Pragt <[hidden email]>
Hi Virtualeyes,

I think if you're just doing to do a println, a System.out.println would work. Haven't tested it though!

Erik

On Aug 21, 2011, at 12:32 AM, virtualeyes wrote:

> def save() {
>       def entity = new Node(params) // entity is def'd, so local scope
>       if(entity.save(flush:true)) {
>               withFormat {
>                       println entity // works, toString() invoked
>                       html {
>                               println entity // error, java.lang.NoSuchMethodError (at withFormat &
> html lines)
>                       }
>               }
>       }
> }
>
> the only way to get things working is to create an instance level variable
> and this.foo it; otherwise nested withFormat closure has no knowledge of
> outer scope. This may be old hat Groovy for some, but was a bit of a
> surprise for me. Is there a way around this? I'd prefer not to have to work
> outside the nested closure if possible.
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/withFormat-is-blind-when-I-am-def-tp3757733p3757733.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>


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

   http://xircles.codehaus.org/manage_email



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

Re: withFormat is blind to def instance

virtualeyes
yes, a "blind" guess indeed ;-)

Mos def the problem is with local variables defined outside of nested closures. My use case is performing a REST redirect uri: to the show action of given controller, which in this case should be "/node/1"

doing:
redirect uri: "/node/"+entity.nid

breaks with mme, while printing entity.nid outside closure scope correctly print 1

creating an instance variable, entityID, solves the problem.

this.entityID = entity.nid
withFormat {
    html { redirect uri: "/node/"+entityID }
}

Moral of the story is: when you def, withFormat goes blind.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: withFormat is blind when I am def

Daniel Henrique Alves Lima-2
In reply to this post by Erik Pragt
    Is this related to callable.resolveStrategy = Closure.DELEGATE_ONLY?

http://www.grails.org/doc/latest/ref/Controllers/withFormat.html
http://groovy.codehaus.org/api/groovy/lang/Closure.html#DELEGATE_ONLY

// MimeTypesGrailsPlugin.groovy

    private addWithFormatMethod(controllers) {
        controllers*.metaClass*.withFormat = { Closure callable ->
            def formats = [:]
            try {
                callable.delegate = new FormatInterceptor()
                callable.resolveStrategy = Closure.DELEGATE_ONLY
                callable.call()
                formats = callable.delegate.formatOptions
            }
            finally {
                callable.delegate = delegate
                callable.resolveStrategy = Closure.OWNER_FIRST
            }

//(...)

class FormatInterceptor {
    def formatOptions = new ListOrderedMap()
    Object invokeMethod(String name,args) {
        if (args.size() > 0 && (args[0] instanceof Closure || args[0]
instanceof Map)) {
            formatOptions[name] = args[0]
        }
        else {
            formatOptions[name] = null
        }
    }
}



virtualeyes wrote:

> def save() {
> def entity = new Node(params) // entity is def'd, so local scope
> if(entity.save(flush:true)) {
> withFormat {
> println entity // works, toString() invoked
> html {
> println entity // error, java.lang.NoSuchMethodError (at withFormat &
> html lines)
> }
> }
> }
> }
>
> the only way to get things working is to create an instance level variable
> and this.foo it; otherwise nested withFormat closure has no knowledge of
> outer scope. This may be old hat Groovy for some, but was a bit of a
> surprise for me. Is there a way around this? I'd prefer not to have to work
> outside the nested closure if possible.
>
>
>  

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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind when I am def

Daniel Henrique Alves Lima-2
    BTW, I was not able to reproduce the issue in a simple test app
using Grails 1.3.7.

// TestController.groovy
package test.xyz

class TestController {

    def index = {

        //def entity = new Node(params) // entity is def'd, so local scope
        //if(entity.save(flush:true)) {
        def entity = new Object()
        if (true) {
            withFormat {
                println entity // works, toString() invoked
                html {                
                    println entity // error, java.lang.NoSuchMethodError
(at withFormat & html lines)
                }
            }
           
        }
    }
}


    Then I accessed http://localhost:8080/test-xyz/test/index

    And I got the following output

java.lang.Object@1786b2ca
java.lang.Object@1786b2ca


    This Groovy script is also producing the same result:

http://groovyconsole.appspot.com/script/541001

   
    Best regards,

          Daniel.


Daniel Henrique Alves Lima wrote:

>    Is this related to callable.resolveStrategy = Closure.DELEGATE_ONLY?
>
> http://www.grails.org/doc/latest/ref/Controllers/withFormat.html
> http://groovy.codehaus.org/api/groovy/lang/Closure.html#DELEGATE_ONLY
>
> // MimeTypesGrailsPlugin.groovy
>
>    private addWithFormatMethod(controllers) {
>        controllers*.metaClass*.withFormat = { Closure callable ->
>            def formats = [:]
>            try {
>                callable.delegate = new FormatInterceptor()
>                callable.resolveStrategy = Closure.DELEGATE_ONLY
>                callable.call()
>                formats = callable.delegate.formatOptions
>            }
>            finally {
>                callable.delegate = delegate
>                callable.resolveStrategy = Closure.OWNER_FIRST
>            }
>
> //(...)
>
> class FormatInterceptor {
>    def formatOptions = new ListOrderedMap()
>    Object invokeMethod(String name,args) {
>        if (args.size() > 0 && (args[0] instanceof Closure || args[0]
> instanceof Map)) {
>            formatOptions[name] = args[0]
>        }
>        else {
>            formatOptions[name] = null
>        }
>    }
> }
>
>
>
> virtualeyes wrote:
>> def save() {
>>     def entity = new Node(params) // entity is def'd, so local scope
>>     if(entity.save(flush:true)) {
>>         withFormat {
>>             println entity // works, toString() invoked
>>             html {                 println entity // error,
>> java.lang.NoSuchMethodError (at withFormat &
>> html lines)
>>             }
>>         }
>>     }
>> }
>>
>> the only way to get things working is to create an instance level
>> variable
>> and this.foo it; otherwise nested withFormat closure has no knowledge of
>> outer scope. This may be old hat Groovy for some, but was a bit of a
>> surprise for me. Is there a way around this? I'd prefer not to have
>> to work
>> outside the nested closure if possible.
>>
>>
>>  


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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind when I am def

virtualeyes
In reply to this post by Daniel Henrique Alves Lima-2
Yes, Daniel, that would explain it, thanks.

Working around it is not a huge deal, really only bit by it in a successful save block, so can live with it, rest'ing is more important.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: withFormat is blind when I am def

Daniel Henrique Alves Lima-2
    But I couldn't reproduce the issue:

http://grails.1312388.n4.nabble.com/Re-withFormat-is-blind-when-I-am-def-tp3758517p3758885.html

virtualeyes wrote:
> Yes, Daniel, that would explain it, thanks.
>
> Working around it is not a huge deal, really only bit by it in a successful
> save block, so can live with it, rest'ing is more important.
>
>  

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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind when I am def

virtualeyes
hmmm, I'm on 2.0, but I wonder if you change index = {...} to index() {...} if you'll be able to reproduce.

Could be groovy specific where variable scope is different between closures & methods with nested closures.

The docs on withFormat also imply that one should use this.foo to define a variable that will be used within nested closures.

Let me know if everything works as is on 1.3.7 when action is a method & not a closure....

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

Re: withFormat is blind when I am def

virtualeyes
Just confirmed on 2.0, if controller action is defined as a closure, then locally scoped variables defined outside of a withFormat block are available within nested closures (html, json, xml, etc.).

Change controller action to a method (recommended approach for 2.0 apparently) and attempt to access locally scoped variables within nested closures blows up with an MME.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: withFormat is blind when I am def

Daniel Henrique Alves Lima-2
  For 1.3.7, replacing a closure by a method will result in a 404 error.
Using 1.3.7 source code in the Groovy web console, it doesn't really
matter if you're invoking a method or a closure:
http://groovyconsole.appspot.com/edit/541001
I think the issue that you're seing might be a bug. To be sure, check
the implementation of withFormat for 2.0.0.

Best regards,

Daniel.

virtualeyes wrote:

> Just confirmed on 2.0, if controller action is defined as a closure, then
> locally scoped variables defined outside of a withFormat block are available
> within nested closures (html, json, xml, etc.).
>
> Change controller action to a method (recommended approach for 2.0
> apparently) and attempt to access locally scoped variables within nested
> closures blows up with an MME.
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Re-withFormat-is-blind-when-I-am-def-tp3758517p3758991.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>  


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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind when I am def

Daniel Henrique Alves Lima-2
  2.0.0 is using AST to add withFormat (MimeTypesTransformer.java). I
don't have any idea how runtime MP differs from compile-time MP :-)

Daniel Henrique Alves Lima wrote:

> For 1.3.7, replacing a closure by a method will result in a 404 error.
> Using 1.3.7 source code in the Groovy web console, it doesn't really
> matter if you're invoking a method or a closure:
> http://groovyconsole.appspot.com/edit/541001
> I think the issue that you're seing might be a bug. To be sure, check
> the implementation of withFormat for 2.0.0.
>
> Best regards,
>
> Daniel.
>
> virtualeyes wrote:
>> Just confirmed on 2.0, if controller action is defined as a closure,
>> then
>> locally scoped variables defined outside of a withFormat block are
>> available
>> within nested closures (html, json, xml, etc.).
>>
>> Change controller action to a method (recommended approach for 2.0
>> apparently) and attempt to access locally scoped variables within nested
>> closures blows up with an MME.
>>


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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind to def instance

Ian Roberts
In reply to this post by virtualeyes
On 21/08/2011 15:58, virtualeyes wrote:
> Interestingly, experimenting I tried:
> html { obj->println obj }(entity)
>
> invoking the closure immediately; it works, but the caveat is that actually
> it does not, since after your invoking of the closure, grails follows,
> calling html {} without args ;-(
>
> Would be nice to pass args to nested withFormat closures; then you wouldn't
> be forced assign instance variable(s)

html { obj -> println obj }.curry(entity)

Ian

--
Ian Roberts               | Department of Computer Science
[hidden email]  | University of Sheffield, UK

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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind to def instance

virtualeyes
Brilliant, did not think of that.

Of course, blows up in 2.0 with MME, this is looking like a bug:

When your action (save, list, show...) is a method and not a closure, not only will withFormat go blind to action method's local variable scope, defining a simple closure will also MME.

def save() {
     def c = {println "hello"} // MME here
     def entity = new Node(params).save(flush:true) // local scope
     ....
     withFormat { html { println entity } } // MME again here when referencing def'd instance
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: withFormat is blind to def instance

Daniel Henrique Alves Lima-2
JIRA it.

virtualeyes wrote:

> Brilliant, did not think of that.
>
> Of course, blows up in 2.0 with MME, this is looking like a bug:
>
> When your action (save, list, show...) is a method and not a closure, not
> only will withFormat go blind to action method's local variable scope,
> defining a simple closure will also MME.
>
> def save() {
>      def c = {println "hello"} // MME here
>      def entity = new Node(params).save(flush:true) // local scope
>      ....
>      withFormat { html { println entity } } // MME again here when
> referencing def'd instance
> }
>
> --
> View this message in context: http://grails.1312388.n4.nabble.com/Re-withFormat-is-blind-when-I-am-def-tp3758517p3759936.html
> Sent from the Grails - user mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>  

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

    http://xircles.codehaus.org/manage_email


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

Re: withFormat is blind to def instance

virtualeyes
Loading...