2014-12-03 145 views
1

我有一個DSL,如果有的話,在每個命令之前調用一個名爲before的閉包。 在我的設置中,我有3個文件:腳本本身 - ScriptScriptBase,通過CompilerConfigurationHandler「附加」到腳本。Groovy基本腳本中的屬性

在腳本中,我可能會或可能不會有一個叫做before的關閉。

before = { 
    //Do stuff. 
} 

注意缺少類型聲明或def。如果我正確理解Groovy,這意味着before是綁定中的一個,並且在使用GroovyShell.evaluate()進行評估時可從外部代碼訪問。

在ScriptBase我做到以下幾點:

class ProductSpecificationBase extends Script { 
    def before = null 
} 

這個腳本的基礎可能會或可能不會在後面覆蓋。 然後,在Handler,我做了before關閉是否在腳本中定義的檢查:

def config = new CompilerConfiguration() 
config.setScriptBaseClass(ScriptBase.class.name) 

def shell = GroovyShell() 
evaluatedScript = shell.evaluate(new File(thePathToScript)) 

if (evaluatedScript.before) { 
    theEvaluationOfMyScript.before() 
} 

代碼工作如果腳本包含before封閉不如預期,但如果它不」它返回一個MissingPropertyException。我看了一下這是什麼意思,看起來ScriptBase中的我的before不屬於財產,所有使用這些我在互聯網上找到的ScriptBase的例子都給出了使用方法的例子。這恐怕不適合我的用例。我如何確保ScriptBase中的封閉被視爲屬性而不是字段(因爲我現在假設它)。

要釋義:如果腳本不包含before閉包,並且未在ScriptBase的擴展中覆蓋,我希望我的代碼不執行if塊。然而,我想evaluatedScript.before的評估爲false,因爲它是一個空/空封閉(即它一直到ScriptBase,發現空封閉) 如果可能,我喜歡避免try/catch方法。

回答

0

在你的例子中,你基本上會調用before屬性的getter。要檢查是否存在名稱(和參數)的方法,請使用respondsTo進行檢查。要看到,如果有一個屬性在所有使用該名稱的使用hasProperty(感謝@dmahapatro指出這一點)

class X { 
    void before() { println 'x' } 
} 

class Y { } 

class Z { 
    def before = { println 'z' } 
} 

def x = new X() 
def y = new Y() 
def z = new Z() 

assert x.respondsTo('before', null) 
assert !y.respondsTo('before', null) 
assert !z.respondsTo('before', null) 

assert !x.hasProperty('before') 
assert !y.hasProperty('before') 
assert z.hasProperty('before') 

x.before() 
z.before() 
+1

'before'是一個封閉。所以你將不得不使用'hasProperty'。 'assert x.hasProperty('before')'和'assert!y.hasProperty('before')'其中'def before = {println「hello」}' – dmahapatro 2014-12-03 16:55:53

+0

@dmahapatro感謝您的提示。我也加了這個答案。 – cfrick 2014-12-03 17:09:58

+0

我認爲,因爲我在ScriptBase中有一個'before'閉包,所以我仍然擁有這個屬性......但事實並非如此,並且屬性丟失了,因爲我將它設置爲null? – kinbiko 2014-12-04 08:24:00