18 Jul 17:34
[groovy-user] Category methods: where do they live at runtime?
From: JRM <oodev@...>
Subject: [groovy-user] Category methods: where do they live at runtime?
Newsgroups: gmane.comp.lang.groovy.user
Date: 2008-07-18 15:37:19 GMT
Subject: [groovy-user] Category methods: where do they live at runtime?
Newsgroups: gmane.comp.lang.groovy.user
Date: 2008-07-18 15:37:19 GMT
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.(Continue reading)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 }
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
}
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
RSS Feed