【问题标题】:How can you change the default Closure resolve strategy for a Groovy script?如何更改 Groovy 脚本的默认闭包解析策略?
【发布时间】:2013-06-24 17:10:21
【问题描述】:

我正在编写一个包含许多全局属性和闭包的大型 Groovy 脚本。所有闭包都用于向现有类添加新方法,例如:

myProperty = 'foo'
// ...more script code...

class MyClass {
    def myProperty = 'default'
}
// ...more script code...

MyClass.metaClass.evaluate = { ->
    myProperty = 'bar'
}

def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "default" instead of "bar"

我的意图是让闭包的 myProperty 引用委托类的 myProperty 而不是全局的。我找到了几种方法来解决这个问题:

1) 在闭包中显式取消引用delegate

MyClass.metaClass.evaluate = { ->
    delegate.myProperty = 'bar'
}

def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "bar" as desired

2) 将闭包的解析策略设置为DELEGATE_ONLY:

def evalClosure = { ->
    myProperty = 'bar'
}
evalClosure.resolveStrategy = Closure.DELEGATE_ONLY
MyClass.metaClass.evaluate = evalClosure

def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "bar" as desired

我更喜欢使用方法 #2 来避免在我的闭包中到处都有“委托”,但我不喜欢为我创建的每个闭包设置解决策略。

我如何告诉 Groovy 默认对所有闭包使用 DELEGATE_ONLY 解析策略?这甚至可能吗?

【问题讨论】:

    标签: groovy scope closures


    【解决方案1】:

    据我所知,我无法更改默认委派策略,您有两种选择:

    1. 将您的脚本拆分为类(这样您就不会在同一范围内拥有脚本级别 myProperty 和类级别 myProperty

    2. 编写一个方法来更改resolveStrategy 并在设置metaClass 时调用它,即:

      def only( Closure c ) {
        c.resolveStrategy = Closure.DELEGATE_ONLY
        c
      }
      
      MyClass.metaClass.evaluate = only { ->
          myProperty = 'bar'
      }
      

    【讨论】:

    • 哈哈。我昨天有第二种方法作为答案,但没有提供,认为 OP 会说“无论如何我必须在每次关闭时使用only(),我宁愿使用closure.resolveStrategy”。我也尝试过使用@Category、继承等,但我总是得到默认的resolveStrategy。然后我说服自己,我必须等待@tim_yates 来启发我们。 :-)
    • @dmahapatro 呵呵,你应该更相信你的直觉 ;-) 我觉得 BDKosher 会不喜欢这个答案,但我想不出任何其他方法(这不是CompilerConfiguration 类)
    • 没错。我也在想ClosureMetaClass 是否会有所帮助,但正如你所说的那样不会。这对我来说是一个很好的大脑锻炼几个小时。 :-)
    • 选项 #2 看起来是目前可以做到的最好的。感谢您的想法(来自你们俩)。我会将此标记为正确答案(直到未来版本的 Groovy 允许它是可配置的)。
    猜你喜欢
    • 1970-01-01
    • 2016-10-15
    • 2010-12-02
    • 2023-04-06
    • 2021-10-19
    • 2019-10-15
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多