2014-12-03 85 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