1

我有一个 DSL,如果存在,before将在每个命令之前调用一个被调用的闭包。在我的设置中,我有 3 个文件:脚本本身 - Script, a ScriptBase,通过 aCompilerConfiguration和 a '附加'到脚本Handler

在脚本中,我可能有也可能没有名为before.

before = {
    //Do stuff.
}

请注意缺少类型声明或def. 如果我正确理解 Groovy,这意味着它before是绑定中的 a,并且在使用 评估时可以从外部代码访问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. 我已经看过这意味着什么,似乎 my beforeinScriptBase不被视为属性,并且ScriptBase我在互联网上找到的所有使用这些 s 的示例都提供了使用方法的示例。恐怕这对我的用例来说是不可行的。如何确保将闭包ScriptBase视为属性而不是字段(正如我现在假设的那样)。

解释一下:if如果脚本不包含before闭包并且没有在ScriptBase. 但是,我希望评估evaluatedScript.beforefalse因为它是一个空/null 闭包(即它一直到ScriptBase,并找到了空闭包)我希望尽可能避免使用 try/catch 方法。

4

1 回答 1

0

在您的示例中,您基本上会调用该before属性的吸气剂。要检查是否有名称(和参数)的方法,请使用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()
于 2014-12-03T16:52:30.680 回答