2014-09-22 68 views
3

我有一個應用程序可以運行腳本來自動執行某些任務。我想在這些腳本中使用元編程來優化代碼大小和可讀性。因此,而不是:Groovy的metaClass的範圍?

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 VM?加載Groovy的類加載器?

我的推理是,如果Groovy元類有VM範圍,那麼我可以在啓動過程中運行一次安裝腳本。每類加載器

+0

'try:... finally:'?那是python嗎? – Will 2014-09-22 13:21:00

+0

@WillP:好抓:-)修正。 – 2014-09-22 13:23:27

回答

3

元類存在[引證需要]

文件/tmp/Qwop.groovy

class Qwop { } 

文件/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方法。

2

這種事情的另一種選擇,對於很多情況更好的是使用擴展模塊。

package demo 

class FactoryExtension { 
    static withResource(Factory instance, Closure c) { 
     def res 
     try { 
      res = instance.allocate() 
      c(res) 
     } finally { 
      res?.close() 
     } 
    } 
} 

編譯並把它在其中包含文件在META-INF/services/org.codehaus.groovy.runtime.ExtensionModule包含這樣的一個jar文件...

moduleName=factory-extension-module 
moduleVersion=1.0 
extensionClasses=demo.FactoryExtension 

然後爲了有人使用您的分機他們只需要將該jar文件放在他們的CLASSPATH上。所有這一切到位,用戶可以做這樣的事情......在擴展模塊

factoryInstance.withResource { res -> 
    ... do something with res ... 
} 

更多信息,請http://docs.groovy-lang.org/docs/groovy-2.3.6/html/documentation/#_extension_modules

相關問題