【问题标题】:Groovy Metaprogramming - Where shall I put it?Groovy 元编程——我应该把它放在哪里?
【发布时间】:2020-07-08 09:29:48
【问题描述】:

我正在编写一个带有一些包和一些类的小型 Groovy libaray。对于其中之一,我想调整MapasType 方法,所以我可以这样写:

import cm.ConfigMap

oldimpl = Map.metaClass.getMetaMethod("asType", [Class] as Class[])

Map.metaClass.asType = { Class c ->
    if (c == ConfigMap) {
        new ConfigMap(rootMap: delegate)
    } else {
        oldimpl.invoke(delegate, c)
    }
}

Map m = [ "key" : "value",
          "a"   : "z" ]

ConfigMap config = m as ConfigMap

这在 Groovy 脚本中按预期工作,但我不知道如果我想在我的库中使用它而不是在脚本中,我可以在那里放置 MOP 指令,以便我的 asType 实现可以是在使用我的库的所有地方都使用过。

【问题讨论】:

标签: groovy metaprogramming


【解决方案1】:

这是一个使用模块描述符的工作解决方案,它允许通过as 运算符从法线贴图中创建我的自定义类ConfigMap 的实例。 允许通过as 将地图投射到我的自定义类ConfigMap

由于 Groovy 2.5 中的每个 Groovy 映射都是java.util.LinkedHashMap 的实例,因此需要提供asType(...) 的增强变体作为LinkedHashMap 的扩展方法:

package cm

class LinkedHashMapExtension {
    static def asType(LinkedHashMap self, Class clazz) {
        def oldAsType = LinkedHashMap.metaClass.getMetaMethod("asType", 
                                                              [Class] as Class[])

        if (clazz == ConfigMap) {
            return new ConfigMap(rootMap: self)
        }

        return oldAsType.invoke(self, clazz)
    }
}

要将上面的类注册为扩展,一个名为org.codehaus.groovy.runtime.ExtensionModule的文件,内容如下:

moduleName=Test module for specifications
moduleVersion=1.0-test
extensionClasses=cm.LinkedHashMapExtension

所有需要的信息都可以在http://groovy-lang.org/metaprogramming.html#module-descriptor找到

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 2016-08-25
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    相关资源
    最近更新 更多