在Groovy的NodeChild上添加动态方法的奇怪行为

我正在使用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" }

相关文章

背景:    8月29日,凌晨4点左右,某服务告警,其中一个...
https://support.smartbear.comeadyapi/docs/soapui/steps/g...
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能...
Scala和Java为静态语言,Groovy为动态语言Scala:函数式编程,...
出处:https://www.jianshu.com/p/ce6f8a1f66f4一、一些内部...
在运行groovy的junit方法时,报了这个错误:java.lang.Excep...