我正在使用Grails
XML Parser解析XML字符串,在获得解析后的NodeChild实例后,我在该实例上添加了动态方法,如下所示:
import grails.converters.XML import groovy.util.slurpersupport.NodeChild NodeChild result = XML.parse("<root></root>") result.getMetaClass().methodA = { return "a" } result.getMetaClass().methodB = { return "b" } println rootNode.methodA() println rootNode.methodB()
现在,我正在调用methodA()并期望打印“a”的行,我得到MissingMethodException,找不到methodA().
我对此进行了一段时间的调查,发现所有动态方法都被我们添加的最后一个动态方法所取代,即在这种情况下:methodB()正在替换(或做某事)methodA(),所以我称之为&首先打印methodB(),正确打印“b”.
这让我想到另一个测试如下:
import grails.converters.XML import groovy.util.slurpersupport.NodeChild String result = "any-other-data-type-instance-here-to-inject-dynamic-methods" result.getMetaClass().methodA = { return "a" } result.getMetaClass().methodB = { return "b" } println rootNode.methodA() println rootNode.methodB()
在这种情况下,两个语句打印都很好.所以问题只在于classNodeChild.我长时间使用exando元类功能,我遇到了这样的问题.任何想法,为什么会发生这种情况?
解决方法
您需要在返回实例之前分配元类方法,否则它将具有旧的元类,而不是具有新方法的新元类.另外,分配给类,而不是实例 – 我不确定你是否只想影响这个实例的元类,但这不是语法.
这有效:
import grails.converters.XML import groovy.util.slurpersupport.NodeChild NodeChild.metaClass.methodA = { return "a" } NodeChild.metaClass.methodB = { return "b" } NodeChild result = XML.parse("<root></root>") println result.methodA() println result.methodB()
请注意,您使用隐式it参数定义方法,但不传递任何内容,因此Groovy传递null.如果您打算让方法没有参数,请使用以下语法:
NodeChild.metaClass.methodA = { -> return "a" } NodeChild.metaClass.methodB = { -> return "b" }