Добавить метод в метакласс - PullRequest
9 голосов
/ 10 декабря 2010

Я просто играю с программированием метаклассов в Groovy.Но внезапно я столкнулся с небольшой проблемой, с которой просто не мог работать ...

Вот простой сценарий:

// 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()

Можно ли использовать метод, но установить первыйпараметр для вызывающего объекта?использование делегата, кажется, не работает ... Назначение методов, которые не ссылаются на вызывающего, не является проблемой.Здесь работает карри?

Спасибо, Инго

1 Ответ

15 голосов
/ 10 декабря 2010

Самый простой способ сделать это - обернуть метод в замыкание следующим образом:

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

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

assert 'variable B'.printValueMethod() == "The value is: 'variable 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'"

Я не думаю, что карри может помочь в этом конкретном случае, поскольку вы не знаете значение делегата во время присвоения метаклассу.

...