实战 Groovy: 使用闭包、ExpandoMetaClass 和类别进行元编程
2009-11-19 00:00:00 来源:WEB开发网解密元编程
清单 11 封装了我在 GroovyTestCase 中编写的演示代码,这样就可以更加严格地对输出进行测试。
清单 11. 使用单元测试分析元编程class MetaTest extends GroovyTestCase{
void testExpandoMetaClass(){
String message = "Hello"
shouldFail(groovy.lang.MissingMethodException){
message.shout()
}
String.metaClass.shout = {->
delegate.toUpperCase()
}
assertEquals "HELLO", message.shout()
String.metaClass = null
shouldFail{
message.shout()
}
}
}
在命令提示中输入 groovy MetaTest 以运行该测试。
注意,只需将 String.metaClass 设置为 null,就可以取消元编程。
但是,如果您不希望 shout() 方法出现在所有 String 中该怎么办呢?您可以仅调整单一实例的 EMC(而不是类),如清单 12 所示:
清单 12. 对单个实例进行元编程void testInstance(){
String message = "Hola"
message.metaClass.shout = {->
delegate.toUpperCase()
}
assertEquals "HOLA", message.shout()
shouldFail{
"Adios".shout()
}
}
如果准备一次性添加或重写多个方法,清单 13 展示了如何以块的方式定义新方法:
清单 13. 一次性对多个方法进行元编程void testFile(){
File f = new File("nonexistent.file")
f.metaClass{
exists{-> true}
getAbsolutePath{-> "/opt/some/dir/${delegate.name}"}
isFile{-> true}
getText{-> "This is the text of my file."}
}
assertTrue f.exists()
assertTrue f.isFile()
assertEquals "/opt/some/dir/nonexistent.file", f.absolutePath
assertTrue f.text.startsWith("This is")
}
更多精彩
赞助商链接