【问题标题】:Groovy CliBuilder: any method defined?Groovy CliBuilder:定义了任何方法?
【发布时间】:2018-08-08 07:55:06
【问题描述】:

我对 Groovy 很陌生。 关于 CliBuilder 中的代码的非常简单的问题。

http://docs.groovy-lang.org/latest/html/gapi/index.html?overview-summary.html

def cli = new CliBuilder(name:'ls')
cli.a('display all files')
cli.l('use a long listing format')
cli.t('sort by modification time')
def options = cli.parse(args)
assert options // would be null (false) on failure
assert options.arguments() == ['*.groovy']
assert options.a && options.l && options.t

CliBuilder 类的行为就像知道我们要提前调用的任何方法一样。 Groovy 的哪些特性可以支持它?

【问题讨论】:

  • 问题不清楚。

标签: groovy command-line-interface


【解决方案1】:

这叫Runtime metaprogramming

如果你想用“动态方法”创建你自己的类,最简单的方法是实现GroovyInterceptable接口并将invokeMethod方法添加到你的类中。

class Interception implements GroovyInterceptable {

    def definedMethod() { }

    def invokeMethod(String name, Object args) {
        'invokedMethod'
    }
}

每当在实例上调用方法时,如果类Interception,则调用invokeMethod而不是。请注意,对于类中实际定义的方法也是如此(例如definedMethod

你可以像这样使用 metaClass 来调用实际的方法

class Interception implements GroovyInterceptable {

    def definedMethod() { }

    def invokeMethod(String name, Object args) {
        if (name == "actualMethod") {
            return metaClass.invokeMethod(this, name, args)
        }
        return "invokedMethod: $name($args)"
    }

    def actualMethod() {
        return 'hello there'
    }
}

这里对actualMethod 的调用仍然通过invokeMethod,但是invokeMethod 包含调用实际方法的逻辑。

还有其他一些方法(参见顶部的链接)来完成类似的行为,但我发现这是最简单的。

请注意,运行时元编程与 @CompileStatic 不兼容,除非您添加 TypeCheckingExtension 来缓解这种情况。

Run Example

【讨论】:

  • 谢谢!它变得清晰。拦截 CliBuilder 实例上的任何方法调用,并将其分派给可以将 calee 名称注册为短选项的方法,然后跳过对 calee 方法的实际方法调用。
猜你喜欢
  • 2012-03-04
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多