4

虽然这不是标准做法,但我很好奇是否可以将方法注入GroovyShell编译上下文。

这个想法是有类似的东西(在Java中):

GroovyShell shell = new GroovyShell();
Script script = shell.parse("test()");
script.run();

我想在哪里动态添加可调用的方法,在哪里test()列出。

Script metaClass我已经尝试了一些弄乱metaClass. 特别是,调用script.getMetaClass().getMethods().add(...)会引发 UnsupportedOperationException。

本质上,我想定义调用 Java 方法而不是基于 Groovy 的方法的 DSL 调用点。我愿意在 Groovy 中编写这部分(并且知道如何做到这一点),但我真的很好奇这是否是一种可行的替代方法,或者如果不是,那么陷阱是什么。

简而言之:我如何动态定义一个GroovyShell知道的方法?

4

2 回答 2

6

有两个非常简单的解决方案:a)典型的“脚本”方法 b)更时髦的方法

a) 只是在您的脚本字符串前面加上一个定义您的方法的字符串。b) 将引用放入绑定中,例如在名称“test”下。该引用的值是一个闭包对象或任何其他具有“call(args)”方法的对象。当执行脚本时,Groovy 看到“test()”,它会首先尝试找到这样的方法,如果没有这样的方法,它会尝试将“test”解析为属性并在绑定中找到它。然后它将使用提供的参数(如果有)调用如此解析的引用(闭包)。

还有更高级的选项,比如提供 CompilerConfiguration,这些都列在“Groovy in Action, 2nd edition”(无耻插件)的 DSL 章节中。

于 2013-09-19T18:20:51.817 回答
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

于 2021-07-01T20:15:02.720 回答