2013-06-24 31 views
0

我在寫一個包含許多全局屬性和閉包的大型Groovy腳本。所有瓶蓋的正在使用新的方法添加到現有的類,例如:如何更改Groovy腳本的默認Closure解決策略?

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" 

我的目的是爲Closure的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解析策略?這甚至有可能嗎?

回答

1

有沒有辦法,我知道的更改默認的代理策略,據我可以看到你有2種選擇:

  1. 拆分將腳本類(所以你不必腳本myProperty水平,在同一個範圍內一流水平myProperty

  2. 寫方法來改變resolveStrategy和調用此當您設置metaClass,即:

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

LOL。我有第二種方法作爲昨天的答案,但沒有提供,認爲OP會說「無論如何我必須使用only()'每個閉包,我寧願使用'closure.resolveStrategy'」。我也嘗試使用'@ Category',繼承等,但我總是得到默認'resolveStrategy'。然後我說服自己,我必須等待@tim_yates啓發我們。 :-) – dmahapatro

+0

@dmahapatro hehe,你應該相信你的直覺更多;-)我覺得BDKosher會不喜歡答案,但我想不出任何其他方式來做到這一點(它不是CompilerConfiguration類的選項) –

+1

沒錯。我也在想,如果'ClosureMetaClass'會幫助你,但正如你所說的那樣。幾個小時對我來說這是一個很好的大腦練習。 :-) – dmahapatro