2009-09-22 14 views
8

Ho riscontrato un problema di meta-programmazione di Groovy che non riesco a risolvere.Meta-programmazione Groovy - aggiunta di metodi statici a Object.metaClass

Quando si aggiunge il metodo foo statico() alla classe FooBar, quindi FooBar.foo() funziona come previsto:

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

Tuttavia, io invece aggiungo lo stesso metodo foo statico() per la classe Object , poi FooBar.foo() non riesce con un MissingMethodException:

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

Perché? Non dovresti Object.metaClass.static.foo = { .. } aggiungere foo() anche a FooBar?

risposta

11

Al fine di ottenere il comportamento che stai cercando è necessario chiamare ExpandoMetaClass.enableGlobally()

Tenete a mente questo modo ha un ingombro di memoria più grande del normale meta-programmazione.

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

+0

Hi! A giudicare dai documenti, questa dovrebbe essere la risposta corretta, ma l'eccezione viene comunque lanciata anche quando ExpandoMetaClass.enableGlobally() viene eseguito all'inizio dello script Groovy. Sei stato in grado di iniettare un metodo statico su Object e averlo a disposizione per estendere gli oggetti? – knorv

1

io non riesco a farlo funzionare anche dopo che ho aggiunto ExpandoMetaClass.enableGlobally() all'inizio dello script:

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