groovy 命令表达式 如何做嵌套表达式?
我正在使用 Groovy 开发一个不错的小型 DSL。
我真的很喜欢具有高阶函数的命令表达式。
我可以做的代码很少:
timerange = from today to tomorrow
这实际上是
timerange = from(today).to(tomorrow)
但现在我想做这样的事情:
difference = difference from today to tomorrow
这应该会导致这样的结果:
difference = difference(from(today).to(event.start))
我总是收到错误:
没有这样的属性:来自类:Script1。
这是一个带有 main 方法的测试类。第三个断言失败:
任何人都可以向我展示如何执行此操作的示例吗?
import groovy.time.DatumDependentDuration /** * Created by IntelliJ IDEA. * User: nils * Date: 2/18/12 * Time: 4:41 PM */ class SimpleTest { def static today = new Date(); def static tomorrow = new Date() + 1; def loadDSL(Closure cl) { cl.delegate = this return cl() } def toMethod = { date -> [to: { timeThing -> if (timeThing instanceof Date) { use(groovy.time.TimeCategory) { (date..timeThing) //return Range } } }] } def from(Date date) { toMethod(date) } def difference(Range range) { range.size() //for the sake of simplicity } static void eval(dslContent, assertion) { SimpleTest runner = new SimpleTest() def dsl = """ run { ${dslContent} } """ def binding = new Binding() binding.run = { Closure cl -> runner.loadDSL(cl) } binding.today = today; binding.tomorrow = tomorrow; GroovyShell shell = new GroovyShell(binding) shell.evaluate(dsl) assert binding.variables.x == assertion } static void main(String[] args) { eval("x = from today to tomorrow", (today..tomorrow)) eval("x = difference(from(today).to(tomorrow))", 2) eval("x = difference from today to tomorrow ", 2) } }
这是完全的例外:
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: from for class: Script1 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50) at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:231) at Script1$_run_closure1.doCall(Script1.groovy:3) 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.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at Script1$_run_closure1.doCall(Script1.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 org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) at SimpleTest.loadDSL(SimpleTest.groovy:17) at SimpleTest$loadDSL.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) at SimpleTest$loadDSL.call(Unknown Source) at SimpleTest$_eval_closure2.doCall(SimpleTest.groovy:48) 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.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1099) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1055) 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.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at Script1.run(Script1.groovy:2) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:580) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:618) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:589) 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$PogoCachedMethodSiteNoUnwrap.invoke(PogoMetaMethodSite.java:247) at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:64) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at SimpleTest.eval(SimpleTest.groovy:54) at SimpleTest$eval.callStatic(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:50) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:157) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:169) at SimpleTest.main(SimpleTest.groovy:62)
i am developing a nice little DSL with Groovy.
I really like the Command Expression with higher order functions.
with little code i can do:
timerange = from today to tomorrow
this is actually
timerange = from(today).to(tomorrow)
but now i would like to do something like this:
difference = difference from today to tomorrow
which should result in something like this:
difference = difference(from(today).to(event.start))
I always get the error:
No such property: from for class: Script1.
Here is a test class with a main Method. The third assertion fails:
Anyone can show me an example how to do this?
import groovy.time.DatumDependentDuration /** * Created by IntelliJ IDEA. * User: nils * Date: 2/18/12 * Time: 4:41 PM */ class SimpleTest { def static today = new Date(); def static tomorrow = new Date() + 1; def loadDSL(Closure cl) { cl.delegate = this return cl() } def toMethod = { date -> [to: { timeThing -> if (timeThing instanceof Date) { use(groovy.time.TimeCategory) { (date..timeThing) //return Range } } }] } def from(Date date) { toMethod(date) } def difference(Range range) { range.size() //for the sake of simplicity } static void eval(dslContent, assertion) { SimpleTest runner = new SimpleTest() def dsl = """ run { ${dslContent} } """ def binding = new Binding() binding.run = { Closure cl -> runner.loadDSL(cl) } binding.today = today; binding.tomorrow = tomorrow; GroovyShell shell = new GroovyShell(binding) shell.evaluate(dsl) assert binding.variables.x == assertion } static void main(String[] args) { eval("x = from today to tomorrow", (today..tomorrow)) eval("x = difference(from(today).to(tomorrow))", 2) eval("x = difference from today to tomorrow ", 2) } }
this here is the complete exception:
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: from for class: Script1 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50) at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:231) at Script1$_run_closure1.doCall(Script1.groovy:3) 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.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at Script1$_run_closure1.doCall(Script1.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 org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) at SimpleTest.loadDSL(SimpleTest.groovy:17) at SimpleTest$loadDSL.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) at SimpleTest$loadDSL.call(Unknown Source) at SimpleTest$_eval_closure2.doCall(SimpleTest.groovy:48) 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.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1099) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1055) 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.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at Script1.run(Script1.groovy:2) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:580) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:618) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:589) 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$PogoCachedMethodSiteNoUnwrap.invoke(PogoMetaMethodSite.java:247) at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:64) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at SimpleTest.eval(SimpleTest.groovy:54) at SimpleTest$eval.callStatic(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:50) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:157) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:169) at SimpleTest.main(SimpleTest.groovy:62)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您将 getDifference 方法添加到返回范围,则可以在表达式末尾调用difference,但除此之外,groovy 不会解析difference从开始到结束作为
difference(from(start).to(end))
,而是作为difference(from).start(to).end
你的测试有一个小变化:
两年半以后还来得及吗?
If you add a
getDifference
method to the returning range, you can calldifference
at the end of your expression, but other than that, groovy won't parsedifference from start to end
asdifference(from(start).to(end))
, but rather asdifference(from).start(to).end
And a small change in your tests:
Is two and half years later too late?
使用命名参数:
区别于:今天,到:明天
查看有关 Groovy 邮件列表讨论的更多信息 [groovy-user]:groovy 命令表达式如何进行嵌套表达?
Use named parameters:
difference from: today, to: tomorrow
See more on the Groovy mailing list discussion [groovy-user]: groovy Command Expression howto do nested expression?