2009-09-22 9 views
8

J'ai rencontré un problème de méta-programmation Groovy que je suis incapable de résoudre.Méta-programmation groovy - ajouter des méthodes statiques à Object.metaClass

Lorsque vous ajoutez la méthode statique foo() à la classe FooBar, puis FooBar.foo() fonctionne comme prévu:

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

Cependant, ajouter au lieu de la même méthode statique foo() à la classe Object , puis FooBar.foo() échoue avec 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: [] 

Pourquoi? Ne devrait pas Object.metaClass.static.foo = { .. } ajouter foo() aussi à FooBar?

Répondre

11

Afin d'obtenir le comportement que vous cherchez, vous devez appeler ExpandoMetaClass.enableGlobally()

Gardez à l'esprit le faire a une plus grande empreinte mémoire que méta-programmation normale.

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

+0

Salut! A en juger par les docs, cela devrait être la bonne réponse, mais l'exception est toujours lancée même lorsque ExpandoMetaClass.enableGlobally() est exécuté au début du script Groovy. Avez-vous été capable d'injecter une méthode statique dans Object et de l'utiliser pour étendre des objets? – knorv

1

Je ne peux pas sembler que cela fonctionne même après que j'ajouté ExpandoMetaClass.enableGlobally() au début du 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 
Questions connexes