WEB开发网
开发学院软件开发Java 实战 Groovy: 使用闭包、ExpandoMetaClass 和类别... 阅读

实战 Groovy: 使用闭包、ExpandoMetaClass 和类别进行元编程

 2009-11-19 00:00:00 来源:WEB开发网   
核心提示: 解密元编程清单 11 封装了我在 GroovyTestCase 中编写的演示代码,这样就可以更加严格地对输出进行测试,实战 Groovy: 使用闭包、ExpandoMetaClass 和类别进行元编程(6), 清单 11. 使用单元测试分析元编程classMetaTestextendsGroov

解密元编程

清单 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") 
} 

上一页  1 2 3 4 5 6 7 8 9 10  下一页

Tags:实战 Groovy 使用

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接