简体   繁体   English

Groovy调用脚本基类中意外的“ get(String)”方法

[英]Groovy invoking unintended “get(String)” method in script's base class

I have a small program that lets its user execute arbitrary Groovy code. 我有一个小程序,它的用户可以执行任意Groovy代码。 I use a base groovy.lang.Script class that provides a number of methods, of which one is named get . 我使用了groovy.lang.Script基类,该基类提供了许多方法,其中一个名为get All this code is written in Java. 所有这些代码都是用Java编写的。

Base class: 基类:

import groovy.lang.Script;
public class ScriptClass extends Script {

    @Override
    public Object run() {
        return null;
    }

    //many other methods

    public String get(String uri) {
        System.out.println("get called with '" + uri + "'");
        return uri;
    }
}

The get(String) method above is intended to be an alias for http(method=GET) . 上面的get(String)方法旨在作为http(method=GET)的别名。

Groovy shell invocation: Groovy Shell调用:

public static void main(String[] args) throws Exception {
    CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
    compilerConfiguration.setScriptBaseClass(ScriptClass.class.getName());

    GroovyShell groovyShell = new GroovyShell(compilerConfiguration);

    Map<String, Object> map = new HashMap<>();
    map.put("no", "NO");

    String template = "yes";
    Script script = groovyShell.parse(template);
    script.setBinding(new Binding(map));

    Object res = script.run();
    System.out.println(res);
}

And that outpus: 那就是:

get called with 'yes' 被叫“是”
yes

The method is not called when I change the input code: 更改输入代码时调用该方法:

String template = "no";

I couldn't find any explanation to why this method is being called, maybe I missed some documentation paragraph. 我找不到为什么调用此方法的任何解释,也许我错过了一些文档段落。

The questions : 问题

  • Why is Groovy calling ScriptClass.get(String) when the script references a variable not defined in the binding? 当脚本引用绑定中未定义的变量时,为什么Groovy调用ScriptClass.get(String)
  • If this behavior is standard/correct, is there a way to prevent the resolution of undefined variables from being routed to ScriptClass.get(String) ? 如果此行为是标准/正确的,是否有办法防止将未定义变量的解析路由到ScriptClass.get(String)

Actually your get method disturbs the metaprogramming abilities of groovy. 实际上,您的get方法会干扰groovy的元编程能力。 See Groovy - difference between get and propertyMissing? 看到Groovy-get和propertyMissing之间的区别? . Quote: When you overloaded get, you lost the propertyMissing functionality. Quote: When you overloaded get, you lost the propertyMissing functionality.

In your example the template is always evaluated. 在您的示例中,始终对模板进行评估。 With the template being no the script returns NO , which is defined in the binding. 模板为no ,脚本返回NO ,这在绑定中定义。 With the template being yes the unbound variable yes is evaluated, which, being unbound, usually always results in calling get and propertyMissing but breaks because get is overridden in your script. 在模板为yes对unbound变量yes进行求值,未绑定的变量yes总是会导致调用getpropertyMissing但由于在脚本中覆盖了get而中断。

You will have to resort to a different method name for get in your script. 您将不得不使用不同的方法名称来get脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM