2009-09-22 22 views
8

Çözemediğim bir Groovy meta programlama problemiyle karşılaştım.Groovy meta-programming - Object.metaClass için statik yöntemler eklemek

sınıf filanca statik yöntem foo() eklerken, ardından FooBar.foo() beklendiği gibi çalışır:

FooBar.metaClass.static.foo = { 
    println "hello" 
} 
FooBar.foo() 

Ancak, bunun yerine sınıf Nesne aynı statik yöntem foo() ekleyin ardından FooBar.foo() bir MissingMethodException başarısız:

Object.metaClass.static.foo = { 
    println "hello" 
} 
FooBar.foo() 
// groovy.lang.MissingMethodException: 
// No signature of method: FooBar.foo() is applicable for argument types: 
//() values: [] 

Bunun nedeni nedir? Object.metaClass.static.foo = { .. }, FooBar'a foo() da eklememeli mi? Eğer ExpandoMetaClass.enableGlobally çağırmanız gerekir kullanarak, istediğiniz davranışı elde etmek için

cevap

11

()

bunun normal meta programlama daha büyük bir bellek alanına sahiptir yapıyor unutmayın.

http://groovy.codehaus.org/api/groovy/lang/ExpandoMetaClass.html#enableGlobally()

+0

Hi! Dokümanlar üzerinden bakıldığında bu doğru cevap olmalı, ancak ExpandoMetaClass.enableGlobally() Groovy komut dosyasının başlangıcında çalıştırıldığında bile istisna hala atılır. Nesne için statik bir yöntem enjekte edebildiniz mi ve nesneleri genişletmek için kullanılabilir mi? – knorv

1

Biliyorum bu programın başında ExpandoMetaClass.enableGlobally() eklendi sonra bile çalışmaya almak gibi olamaz:

ExpandoMetaClass.enableGlobally(); 
Object.metaClass.static.Log = { msg -> 
    println(msg); 
} 

class Foo { 
    def l() { 
     Log("Foo:l().log"); // works 
    } 
} 

Object.Log("Object.log"); // works 
String.Log("String.log"); // works 

Log("script.log");  // works 


foo = new Foo(); 

foo.l(); 
foo.Log("foo.log"); // works 
Foo.Log("Foo.log") // Does not work