我有一个可以运行脚本来自动执行某些任务的应用程序。我想在这些脚本中使用元编程来优化代码大小和可读性。所以而不是:
try {
def res = factory.allocate();
... do something with res ...
} finally {
res.close()
}
我想
Factory.metaClass.withResource = { c ->
try {
def res = factory.allocate();
c(res)
} finally {
res.close()
}
}
所以脚本作者可以这样写:
factory.withResource { res ->
... do something with res ...
}
(我可以做适当的错误处理等)。
现在我想知道我何时以及如何能够/应该实现这一点。我可以将元类的操作附加到每个脚本前面的标头中,但我担心如果两个用户同时运行脚本(同时访问元类)会发生什么。
元类的范围是什么?编译器?脚本环境? Java 虚拟机?加载 Groovy 的类加载器?
我的理由是,如果 Groovy 元类具有 VM 范围,那么我可以在启动期间运行一次安装脚本。
Metaclasses exist per classloader [citation needed]:
File /tmp/Qwop.groovy
:
class Qwop { }
File /tmp/Loader.groovy
:
Qwop.metaClass.bar = { }
qwop1 = new Qwop()
assert qwop1.respondsTo('bar')
loader = new GroovyClassLoader()
clazz = loader.parseClass new File("/tmp/Qwop.groovy")
clazz.metaClass.brap = { 'oh my' }
qwop = clazz.newInstance()
assert !qwop.respondsTo('bar')
assert qwop1.respondsTo('bar')
assert qwop.brap() == "oh my"
assert !qwop1.respondsTo('brap')
// here be custom classloaders
new GroovyShell(loader).evaluate new File('/tmp/QwopTest.groovy')
以及一个测试作用域元类的脚本(/tmp/QwopTest.groovy
):
assert !new Qwop().respondsTo('bar')
assert new Qwop().respondsTo('brap')
执行:
$ groovy Loaders.groovy
$
如果您有一组定义良好的类,您可以在这些类之上应用元编程由你的类加载器加载,根据brap
方法已添加。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)