Groovy缺失法
我正试图根据文档动态地向Groovy类添加一个新方法。 下面是我实现methodMissing方法的类:Groovy缺失法,groovy,Groovy,我正试图根据文档动态地向Groovy类添加一个新方法。 下面是我实现methodMissing方法的类: class AlexTest { def methodMissing(String name, args){ println "Method missing is called" def cachedMethod = { Object[] varArgs -> println "Hi! ${varArgs}"
class AlexTest {
def methodMissing(String name, args){
println "Method missing is called"
def cachedMethod = { Object[] varArgs ->
println "Hi! ${varArgs}"
}
AlexTest.metaClass."${name}" = cachedMethod
return cachedMethod(args)
}
}
下面是另一个使用AlexTest类的groovy脚本:
def alexTest = new AlexTest()
alexTest.hi("Alex")
alexTest.hi("John")
我希望“methodmissingscalled”只被调用一次,因为方法“hi”会被“引入”到methodMissing中。但是,methodMissing被调用了两次,就好像“hi”方法从未被引入到AlexTest类中一样
我也尝试了不同的做法:
class AlexTest {
AlexTest() {
def mc = new ExpandoMetaClass(AlexTest, false, true)
mc.initialize()
this.metaClass = mc
}
def methodMissing(String name, args){
println "Method missing is called"
def cachedMethod = { Object[] varArgs ->
println "Hi! ${varArgs}"
}
// note that this is calling metaClass inside the instance
this.metaClass."${name}" = cachedMethod
return cachedMethod(args)
}
}
哪种方法有效,但只适用于单个实例。因此,如果我创建两个AlexTest实例,并调用'hi'方法,我将得到两条“methodmissing is called”消息。
有人能告诉我解释这种行为的文档吗
提前谢谢
问候,
Alex在第一次尝试开始时添加以下内容:
ExpandoMetaClass.enableGlobally()
它适用于我的v2.0.1版本
如果希望在类实例的基础上启用,请说明一种方法:
class AlexTest {
AlexTest() {
def mc = new ExpandoMetaClass(AlexTest, false, true)
mc.initialize()
this.metaClass = mc
}
def methodMissing(String name, args){
println "Method missing is called"
def cachedMethod = { Object[] varArgs ->
println "Hi! ${varArgs}"
}
this.metaClass."${name}" = cachedMethod
return cachedMethod(args)
}
}
def alexTest = new AlexTest()
alexTest.hi("Alex")
alexTest.hi("John")
这个剧本怎么样?这确保methodMissing为类引用实现,并应用于引用它的所有实例
class AlexTest {
}
mc = AlexTest.metaClass
mc.methodMissing = {String name, args=[:] ->
println "Method missing is called"
def cachedMethod = { Object[] varArgs ->
println "Hi! ${varArgs}"
}
mc."${name}" = cachedMethod
cachedMethod(args)
}
def alexTest = new AlexTest()
alexTest.hi("Alex")
alexTest.hi("John")
def myTest = new AlexTest()
myTest.hi("Walter")
myTest.hi("Hank")
//Prints
Method missing is called
Hi! [Alex]
Hi! [John]
Hi! [Walter]
Hi! [Hank]
尽管在全局范围内启用ExpandoMetaClass同样有效,但只需花费很少的额外内存。:) 但它需要大量内存。:)迈克尔·复活节:是的,我的剧本底部有这个。但正如你提到的,它是每个实例。不是全班的。因此,每当在全新实例上调用“hi”方法时,“methodMissing”就会被调用。这不是我想要的。嗯。。。正如dmahapatro指出的(以及从javadoc中),ExpandoMetaClass.enableglobal()似乎是内存密集型的。但我不确定它的强度有多大。另外,我应该在哪里调用此方法,比如在web应用程序中?在上下文初始化过程中?我已经尝试过了,而且效果很好。我不喜欢它的原因是因为我想在AlexTest类本身中保留“methodMissing”。我不确定在一个完整的应用程序中,在哪里放置该方法是合适的。我想我来自Java背景,所有东西都必须在一个类中。如果AlexTest已经期望“hi”,那么最好在
AlexTest
中实现hi()
。我希望你明白了。是的,我同意。在这个特定的示例中,最好直接在AlexTest中实现hi()。但我说的是生成动态方法,比如GORM中的finder方法。我很好奇戈姆是怎么做到的。是否使用ExpandoMetaClass.EnableGlobal()?不,他们不使用该设置。所有可能的动态方法都以grails数据存储gorm
模块中的finder
的形式出现在grails数据映射中,并在运行时使用反射将其添加到域类中。要看的类是。也可以浏览@检察官