[groovy-user] Category methods: where do they live at runtime?

0 views
Skip to the first unread message

JRM

unread,
18 Jul 2008, 11:37:1918/07/2008
to us...@groovy.codehaus.org
I've searched the list and groovy docs for an answer to this, but I've
been unable to find an answer so far. If it's been covered already,
my apologies.

Is it possible (under Groovy 1.5.4) from within the scope of a
category usage to get a reference at runtime to the methods that are
added from the category? I can't seem to figure out where references
to those methods are stored. They aren't available in the MetaClass
or the binding. Where do they come from? It's all so magical. :-)

Here is a script that demonstrates trying to find them in the script's
class methods and metaClass methods:


public class MyMagicCategory {

static def whereDoILive( Script self ) {
println "Hello. I'm right here."
}
}

use (MyMagicCategory) {
whereDoILive()
def foundInMethods = this.class.methods.find{ it.name ==
"doSomething" } != null
def foundInMetaMethods = this.metaClass.metaMethods.find{ it.name
== "doSomething" } != null

assert foundInMethods || foundInMetaMethods
}

Output:
Hello. I'm right here.
Exception thrown: java.lang.AssertionError: Expression:
(foundInMethods || foundInMetaMethods). Values: foundInMethods =
false, foundInMetaMethods = false

java.lang.AssertionError: Expression: (foundInMethods ||
foundInMetaMethods). Values: foundInMethods = false,
foundInMetaMethods = false
at Script15$_run_closure1.doCall(Script15:14)
at Script15$_run_closure1.doCall(Script15)
at Script15.run(Script15:9)


Thanks for the help!

--
Jason

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

http://xircles.codehaus.org/manage_email


Martin C. Martin

unread,
18 Jul 2008, 13:02:5118/07/2008
to us...@groovy.codehaus.org
What do you want to use this for? Maybe there's a simpler way.

Take a look at GroovyCategorySupport.getCategoryMethods()

Best,
Martin

JRM

unread,
20 Jul 2008, 22:15:4220/07/2008
to us...@groovy.codehaus.org
Well, hopefully I can answer your question in an understandable way.
You might regret that you asked. ;-)

What I'm trying to do is dynamically add methods to a Script which is
also dynamic. What I've got is a Web-based Groovy Console, much like
the GroovyConsole that is included in the Groovy distro. I want to
take the script that the user inputs in the Console and add some
general purpose utility methods to it. Those utility methods
currently exist in Groovy Categories that are deployed in a filesystem
location that can be reached from our web application. The Groovy
Categories can change as well (i.e., we might add/remove/change
methods defined in them while our app is deployed and running in the
container). So I want to be able to dynamically read in the
Categories and add their methods to the user's script. I have a
script named GroovyWebConsole.groovy that invokes the user's script
via a GroovyShell. So I have the capability to add stuff to the Script
object or the binding of that script object before I execute it. One
approach that seems to work is to have my GroovyWebConsole code
wrapped in a use clause which pulls in all my Categories. I can then
bind the Category methods into the binding of the user's script before
it executes. That works. The drawback is that since I haven't been
able to find a way to dynamically get references to the Category
methods, I can't set them on the binding dynamically. I've proven
that setting them on the binding manually works, though. I've tried
other approaches using normal Groovy classes and ExpandoMetaClass to
add methods to the Script instance, but I was unable to get that to
work. I referred to the ExpandoMetaClass docs on the groovy website,
and they were very helpful, but I just couldn't get it to work. I
might be missing some kind of trick though. I'm fairly new to working
with Groovy's metaclass capabilities. So after several iterations of
trying to get ExpandoMetaClass to work, I've resorted to an approach
with Categories. Maybe I'm in the weeds. :-)

I'll stop there for now. There is a lot more detail than this, but I
don't want to push it or you might give up on me and figure there's no
hope. ;-)

I'm very open to better ways to do this, if one exists. For instance,
is there a better way to do this with closures or something? Thanks
for the help.

--
Jason

Saager Mhatre

unread,
23 Jul 2008, 03:21:2823/07/2008
to us...@groovy.codehaus.org
MetaClass.respondsTo ... ?
--
Saager Mhatre

Jason Mihalick

unread,
30 Jul 2008, 09:38:4230/07/2008
to us...@groovy.codehaus.org

Thanks for the response on this, Martin.

I was able to get a solution to work with your suggestion. Using
GroovyCategorySupport.getCategoryMethods() I was able to add methods into
the Script's binding and access them from scripts that the user creates in
the web console. Works good enough for me and I'm quite pleased with being
able to have access to "global" methods from within a script without having
to type in a 'use' clause.

--
Jason
--
View this message in context: http://www.nabble.com/Category-methods%3A-where-do-they-live-at-runtime--tp18532553p18733426.html
Sent from the groovy - user mailing list archive at Nabble.com.

Reply all
Reply to author
Forward
0 new messages