Created
September 23, 2011 16:08
-
-
Save sit/1237768 to your computer and use it in GitHub Desktop.
A puzzle about why Groovy behaves a certain way with respect to propertyMissing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A minimal script to demonstrate the problem discussed at | |
* http://stackoverflow.com/questions/7524340/how-do-groovy-scripts-interact-with-propertymissing | |
*/ | |
class Thing { | |
} | |
class FooSyntax { | |
def myKeyword(Thing t) { println "Hello Foo " + t.toString(); } | |
/* | |
* With this method uncommented, neither foo in the script works. | |
* With this method commented, the first foo (with bar) works, | |
* the second foo (with baz) does not (as expected). | |
* | |
* Why is this? | |
*/ | |
// def propertyMissing(String name) { | |
// println "no foo for ${name}" | |
// } | |
} | |
class ScriptSyntax { | |
def foo(Closure cl) { | |
def f = new FooSyntax(); | |
f.with cl | |
} | |
def thing() { | |
new Thing() | |
} | |
def dispatchKeyword(String methodName, Object args) { | |
// Sanity check methodName | |
invokeMethod(methodName, args) | |
} | |
} | |
def runner(String text) { | |
def source = new GroovyCodeSource(text, "inlineScript", "inline.groovy") | |
def script = new GroovyClassLoader().parseClass(source).newInstance(binding) as Script | |
def dsl = new ScriptSyntax() | |
script.metaClass.methodMissing = { name, args -> dsl.dispatchKeyword(name, args) } | |
script.run() | |
} | |
runner("""bar = thing() | |
foo { myKeyword bar } | |
foo { myKeyword baz }""") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a problem with your use of .with() on line 27. The code you want to use for executing the closure is:
Your example will then work as you want it to. The problem is that the
with()
method modifies the closure in a similar way, but changes the default resolution strategy.