groovy绑定问题

时间:2012-05-16 14:39:50

标签: binding groovy

我有以下示例代码

import org.codehaus.groovy.control.CompilerConfiguration

abstract class MyClass extends Script {

    void testMethod(Integer x) {
        println "x = $x"
    }
}

public static void main(String[] args) {
    compilerConfiguration = new CompilerConfiguration();
    compilerConfiguration.setScriptBaseClass("MyClass");
    GroovyShell shell = new GroovyShell(new Binding(), compilerConfiguration);
    shell.evaluate("testMethod 1")
}

当我运行此类时,它会打印x = 1 现在,如果我将"testMethod 1"更改为"testMethod -1"则会失败

Caught: groovy.lang.MissingPropertyException: No such property: testMethod for class: Script1
groovy.lang.MissingPropertyException: No such property: testMethod for class: Script1
    at Script1.run(Script1.groovy:1)
    at Test.run(Test.groovy:15)

现在我将"testMethod -1"更改为"testMethod (-1)"。它再次起作用并打印x = -1

我需要了解的是为什么Groovy要求用括号表示负数。

1 个答案:

答案 0 :(得分:1)

因为没有括号,假设您试图从名为testMethod的属性中减去1(即:testMethod - 1

您需要括号来通知解析器这是方法调用而不是减法操作


修改

我想出了一个可怕的方法让它发挥作用:

import java.lang.reflect.Method
import org.codehaus.groovy.control.CompilerConfiguration

abstract class MyClass extends Script {
  private methods = [:]

  class MinusableMethod {
    Script declarer
    Method method
    MinusableMethod( Script d, Method m ) {
      this.declarer = d
      this.method = m
    }
    def minus( amount ) {
      method.invoke( declarer, -amount )
    }
  }

  public MyClass() {
    super()
    methods = MyClass.getDeclaredMethods().grep {
      it.name != 'propertyMissing' && !it.synthetic
    }.collectEntries {
      [ (it.name): new MinusableMethod( this, it ) ]
    } 
  }

  def propertyMissing( String name ) {
    methods[ name ]
  }

  void testMethod(Integer x) {
      println "x = $x"
  }
}

static main( args ) {
  def compilerConfiguration = new CompilerConfiguration();
  compilerConfiguration.setScriptBaseClass( 'MyClass' );
  GroovyShell shell = new GroovyShell(new Binding(), compilerConfiguration);
  shell.evaluate("testMethod - 1")
}

这可能会在其他条件下中断

从长远来看,让人们编写有效的脚本可能是更好的选择......