绑定和闭合 groovy

发布于 2024-09-09 05:18:13 字数 383 浏览 4 评论 0原文

我不知道如何在 Groovy 中使用闭包绑定。我编写了一个测试代码,在运行它时,它说,在作为参数传递的闭包上缺少方法 setBinding

void testMeasurement() {
    prepareData(someClosure)
}
def someClosure = {
  assertEquals("apple", a)
}


  void prepareData(testCase) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.setBinding(binding)
    testCase.call()

  }

I don't know how to use binding with closures in Groovy. I wrote a test code and while running it, it said, missing method setBinding on the closure passed as parameter.

void testMeasurement() {
    prepareData(someClosure)
}
def someClosure = {
  assertEquals("apple", a)
}


  void prepareData(testCase) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.setBinding(binding)
    testCase.call()

  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暖伴 2024-09-16 05:18:13

这适用于 Groovy 1.7.3:

someClosure = {
  assert "apple" == a
}
void testMeasurement() {
  prepareData(someClosure)
}
void prepareData(testCase) {
  def binding = new Binding()
  binding.setVariable("a", "apple")
  testCase.setBinding(binding)
  testCase.call()
}
testMeasurement()

在此脚本示例中,setBinding 调用在脚本绑定中设置 a (如您所见 来自 Closure 文档,没有 setBinding 调用)。因此,在 setBinding 调用之后,您可以调用

println a

它,它将打印出“apple”。

因此,要在类中执行此操作,您可以为闭包设置委托(当在本地找不到属性时,闭包将恢复为该委托)像这样:

class TestClass {
  void testMeasurement() {
    prepareData(someClosure)
  }

  def someClosure = { ->
    assert "apple" == a
  }

  void prepareData( testCase ) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.delegate = binding
    testCase.call()
  }
}

它应该从委托类(在本例中为绑定)中获取 a 的值

此页面详细介绍了闭包中委托的使用和变量的范围。

事实上,您不使用 Binding 对象,而是使用应该能够使用像这样的简单地图:

  void prepareData( testCase ) {
    testCase.delegate = [ a:'apple' ]
    testCase.call()
  }

希望有帮助!

This works for me with Groovy 1.7.3:

someClosure = {
  assert "apple" == a
}
void testMeasurement() {
  prepareData(someClosure)
}
void prepareData(testCase) {
  def binding = new Binding()
  binding.setVariable("a", "apple")
  testCase.setBinding(binding)
  testCase.call()
}
testMeasurement()

In this script example, the setBinding call is setting a in the scripts binding (as you can see from the Closure documentation, there is no setBinding call). So after the setBinding call, you can call

println a

and it will print out "apple"

So to do this in the class, you can set the delegate for the closure (the closure will revert back to this delegate when a property cannot be found locally) like so:

class TestClass {
  void testMeasurement() {
    prepareData(someClosure)
  }

  def someClosure = { ->
    assert "apple" == a
  }

  void prepareData( testCase ) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.delegate = binding
    testCase.call()
  }
}

And it should grab the value fro a from the delegate class (in this case, a binding)

This page here goes through the usage of delegate and the scope of variables in Closures

Indeed, instead of using a Binding object, you should be able to use a simple Map like so:

  void prepareData( testCase ) {
    testCase.delegate = [ a:'apple' ]
    testCase.call()
  }

Hope it helps!

瀟灑尐姊 2024-09-16 05:18:13

这确实是奇怪的行为:删除 someClosure 声明前面的“def”使脚本在 JDK1.6 Groovy:1.7.3 中工作

更新:这是在上面的答案中发布的。我的错误是重复它。
更新:为什么它有效?如果没有 def,第一行将被视为属性分配,它调用 setProperty 并使变量在绑定中可用,稍后将进行解析。
def 应该 的效果与 (http:// /docs.codehaus.org/display/GROOVY/Groovy+Beans

someClosure = {
    assert "apple", a
    print "Done"
}

void testMeasurement() {
    prepareData(someClosure)
}

void prepareData(testCase) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.setBinding(binding)
    testCase.call()
}
testMeasurement()

我可以通过以下代码重现您提到的问题。但我不确定这是否是使用绑定的正确方法。 GroovyDocs 表示它们将与脚本一起使用。您能否向我指出建议使用闭包绑定的文档。

class TestBinding extends GroovyTestCase {
    void testMeasurement() {
        prepareData(someClosure)
    }

    def someClosure = {
        assertEquals("apple", a)
    }

    void prepareData(testCase) {
        def binding = new Binding()
        binding.setVariable("a", "apple")
        //this.setBinding(binding)
        testCase.setBinding(binding)
        testCase.call()
    }
}

这在 groovy 邮件列表上得到了回答:

在脚本中,def foo 将创建一个局部变量,而不是一个属性
(私有字段+ getter/setter)。
将脚本想象为 run() 或 main() 方法的主体。
这就是定义局部变量的位置和方式。

This is really strange behaviour: removing the "def" in front of someClosure declaration makes the script work in JDK1.6 Groovy:1.7.3

Update: This was posted in the answer above. My mistake to repeat it.
Update: Why it works? Without a def first line is taken as a property assignment which calls setProperty and makes the variable available in binding, which is resolved later.
a def should have worked as well as per (http://docs.codehaus.org/display/GROOVY/Groovy+Beans)

someClosure = {
    assert "apple", a
    print "Done"
}

void testMeasurement() {
    prepareData(someClosure)
}

void prepareData(testCase) {
    def binding = new Binding()
    binding.setVariable("a", "apple")
    testCase.setBinding(binding)
    testCase.call()
}
testMeasurement()

I could reproduce the problem you mention by following code. But i am not sure if this is the correct way to use Binding. GroovyDocs says they are to be used with scripts. Could you point me to documentation which suggests such usage of Binding with Closures.

class TestBinding extends GroovyTestCase {
    void testMeasurement() {
        prepareData(someClosure)
    }

    def someClosure = {
        assertEquals("apple", a)
    }

    void prepareData(testCase) {
        def binding = new Binding()
        binding.setVariable("a", "apple")
        //this.setBinding(binding)
        testCase.setBinding(binding)
        testCase.call()
    }
}

This was answered on groovy mailing list:

In a script, def foo will create a local variable, not a property
(private field + getter/setter).
Think of a script a bit like if it's the body of a run() or main() method.
That's where and how you can define local variables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文