Binding groovy绑定问题

Binding groovy绑定问题,binding,groovy,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 C

我有下面的示例代码

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要求用括号表示负数。

因为没有括号,它假设您试图从名为
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")
}
但是在其他条件下,这可能会中断


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

因为如果没有括号,它假设您试图从名为
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")
}
但是在其他条件下,这可能会中断


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

我是否可以忽略这种行为?@Manoj不是真的…试图想出一种方法,但没有简单的方法mind@Manoj提出了一个解决方案,但我不推荐它(不过,尝试和编写它很有趣);-)测试方法0-1可能会起作用。如果代码不太复杂,您可以自己解析字符串并添加()或“0”。大多数情况下,我建议不要扭曲编译器来编译它不是专门为编译而设计的东西——仅仅因为Ruby用户认为Ruby将编译slop来弥补他们不想编写自己的解释器这一事实并不意味着扭曲的半清晰DSL能够在现有语言中编译是一个好方法事情——如果需要的话,我更喜欢创建一个真正的DSL,你可以控制所有的语法。有没有我可以覆盖这种行为?@Manoj不是真的…试图想出一种方法,但没有简单的方法mind@Manoj提出了一个解决方案,但我不推荐它(不过,尝试和编写它很有趣);-)测试方法0-1可能会起作用。如果代码不太复杂,您可以自己解析字符串并添加()或“0”。大多数情况下,我建议不要扭曲编译器来编译它不是专门为编译而设计的东西——仅仅因为Ruby用户认为Ruby将编译slop来弥补他们不想编写自己的解释器这一事实并不意味着扭曲的半清晰DSL能够在现有语言中编译是一个好方法我更喜欢创建一个真正的DSL,如果需要的话,你可以控制所有的语法。