虽然这不是标准做法,但我很好奇是否可以将方法注入GroovyShell
编译环境。
这个想法是有(像Java):
GroovyShell shell = new GroovyShell();
Script script = shell.parse("test()");
script.run();
我想动态添加可调用的方法,其中列出了test()
。
我已经尝试过使用Script
metaClass
,但是我没有看到从Java实际操作metaClass
的方法。特别是,调用script.getMetaClass().getMethods().add(...)
会抛出UnsupportedOperationException。
本质上,我想定义调用Java方法而不是基于Groovy方法的DSL调用点。我愿意在Groovy中写这个部分(我知道如何做到这一点),但我真的很好奇,如果这是一个可行的替代方法,或者如果不是,那么陷阱是什么。
简而言之:如何动态定义GroovyShell
知道的方法?
答案 0 :(得分:4)
这有两个非常简单的解决方案: a)典型的“脚本”方法 b)更加时髦的方法
a)只是在您的script-String前面添加一个定义方法的String。 b)正在引用绑定,例如在“测试”的名称下。该引用的值是Closure对象或具有“call(args)”方法的任何其他对象。 当执行脚本时,Groovy看到“test()”,它将首先尝试找到这样的方法,如果没有这样的方法,它会尝试将“test”解析为属性并在绑定中找到它。然后它将使用提供的参数(如果有的话)调用如此解析的引用(闭包)。
还有更高级的选项,如提供CompilerConfiguration,这些选项都列在“Groovy in Action,第2版”(无耻插件)的DSL章节中。
答案 1 :(得分:0)
我用 MethodClosure 搜索示例但没有运气。这对我有用:
Closure whoami = new Closure(this){
@Override
public Object call(Object... args) {
//add custom logic here or read passed args
return "javatar";
}
};
Binding b = new Binding();
b.setVariable("whoami", whoami);
之后,我可以在我的 groovy 脚本中使用 whoami 作为方法
whoami()
如果是简单的方法,我更喜欢使用 Dierk 的选项 A:
<块引用>只需在脚本字符串前面加上定义方法的字符串即可。
但是如果它很复杂,我使用Closure :D