在Groovy Shell中使用Groovy类别

5

我正在使用Groovy类别(categories)进行DSL开发,希望找到一种方法可以在Groovy Shell中使用我的DSL,而不需要为每个命令显式地编写use(MyCategory){ myObject.doSomething() }

例如,假设我有以下玩具类别:

class MyCategory {
    static Integer plus(Integer integer, String string){
        return integer + Integer.valueOf(string)
    }
}

接着,我可以在 groovysh 中按如下方式使用这个类别:

groovy> use(MyCategory){ 2 + '3' } //gives 5

那么,有没有办法为所有groovysh命令全局设置MyCategory,这样每次都不需要用use(MyCategory) { ... }包装我的命令呢?例如:

groovy> useGlobally(MyCategory); //call something like this only once
groovy> 2 + '3' //automatically uses MyCategory and gives 5
1个回答

2
类别的概念是为了限定元编程的范围。在这种情况下,为什么不使用metaClass呢?
groovy:000> class MyCategory {
groovy:001>     static Integer plus(Integer integer, String string){
groovy:002>         return integer + Integer.valueOf(string)
groovy:003>     }
groovy:004> }
===> true
groovy:000> Integer.metaClass.mixin MyCategory
===> null
groovy:MyCategory@131fa4b> 2 + '4'
===> 6
groovy:MyCategory@131fa4b> 

更新:有很多方法可以遍历静态方法的第一个参数,并将它们混合到相应的参数类型类中。
class MyCategory {
    static global() {
        MyCategory.metaClass.methods
            .findAll { it.isStatic() && !it.name.startsWith("__") && it.name != "global" }
            .each { it.nativeParameterTypes[0].mixin MyCategory }
    }

    static Integer plus(Integer integer, String string){
        return integer + Integer.valueOf(string)
    }

    static String yell(String a, times) {
      a.toUpperCase() * times + "!!!"
    }
}


MyCategory.global()


assert "a".yell(3) == "AAA!!!"
assert 2+'3' == 5

谢谢,这几乎是我想要找的。但是如果MyCategory包含许多不同类的覆盖,那么我需要手动为每个类指定mixin(例如Integer)。有没有自动执行此操作的方法? - Stanislav Poslavsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接