我有一个DSL,如果存在,将在每个命令之前调用一个名为before
的闭包。
在我的设置中,我有3个文件:脚本本身 - Script
,ScriptBase
,附加'通过CompilerConfiguration
和Handler
。
在脚本中我可能有也可能没有名为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
。我已经了解了这意味着什么,似乎我before
ScriptBase
中的ScriptBase
并未被视为属性,所有使用这些ScriptBase
的示例我在互联网上找到了使用方法的例子。对于我害怕的用例,这是不可行的。如何确保if
中的闭包被视为属性而不是字段(正如我现在假设的那样)。
要解释一下:如果脚本不包含before
闭包,并且未在{{1的扩展名中覆盖,我希望我的代码不执行ScriptBase
块}}。但是,我希望evaluatedScript.before
的评估为false
,因为它是一个空的/ null Closure(即它一直到ScriptBase
,并发现空闭包)
如果可能的话,我想避免使用try / catch方法。
答案 0 :(得分:0)
在您的示例中,您基本上会调用before
属性的getter。要检查,是否有名称(和params)的方法检查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()