2010-12-10 18 views
9

Po prostu gram z programowaniem metaclass w Groovy. Ale nagle została skierowana mały problem, który po prostu nie mógł dostać pracę ...Dodaj metodę do metaklasy

Oto prosty skrypt:

// define simple closure 
def printValueClosure = { 
println "The value is: '$delegate'" 
} 

String.metaClass.printValueClosure = printValueClosure 

// works fine 
'variable A'.printValueClosure() 



// define as method 
def printValueMethod(String s){ 
println "The value is: '$s'" 
} 

// how to do this!? 
String.metaClass.printValueMethod = this.&printValueMethod(delegate) 

'variable B'.printValueMethod() 

Czy możliwe jest użycie metody jednak ustawić pierwszy parametr do powołania obiekt? używanie delegata wydaje się nie działać ... Przypisanie metod, które nie odwołują się do wywołującego, nie stanowi problemu. Czy tu działa curry?

Dzięki, Ingo

Odpowiedz

14

Najprostszą drogą do osiągnięcia tego celu jest zawinąć metodę w zamknięciu, tak jak poniżej:

def printValueMethod(String s){ 
    println "The value is: '$s'" 
} 

String.metaClass.printValueMethod = { -> printValueMethod(delegate) } 

assert 'variable B'.printValueMethod() == "The value is: 'variable B'" 

The idomatic sposób dodać metodę bez użycia zamknięcia byłoby utworzyć klasę kategorii i wymieszać je w taki sposób:

class PrintValueMethodCategory { 
    static def printValueMethod(String s) { 
     println "The value is: '$s'" 
    } 
} 

String.metaClass.mixin(PrintValueMethodCategory) 

assert 'variable B'.printValueMethod() == "The value is: 'variable B'" 

nie sądzę currying może pomóc w tym konkretnym przypadku, ponieważ nie znają wartość o f delegata w momencie przypisania do metaklasu.

+0

Nice. Dzięki. Nigdy o tym nie myślałem ... Czy istnieje również wygodny sposób dodania dużej ilości statycznej metody pomocniczej do klasy (nie poprzez kategorię). Na przykład Apache Commons IO FileUtils do klasy plików? – Ingo

+0

ah ... Twoja edycja odpowiada również na dodatkowe pytanie. Dzięki jeszcze raz. – Ingo