Как изменить поведение метода в Groovy, используя этот метод в метаклассе - PullRequest
5 голосов
/ 28 мая 2009

Я бы хотел «испортить» метод plus в Groovy следующим образом:

Integer.metaClass.plus {Integer n -> delegate + n + 1}
assert 2+2 == 5

Я получаю StackOverflowException (что неудивительно).

Есть ли способ использовать "оригинальный" метод plus внутри замыкания метакласса?

Ответы [ 2 ]

7 голосов
/ 29 мая 2009

Отличный идиоматический способ - сохранить ссылку на старый метод и вызвать его внутри нового.

def oldPlus = Integer.metaClass.getMetaMethod("plus", [Integer] as Class[])

Integer.metaClass.plus = { Integer n ->
    return oldPlus.invoke(oldPlus.invoke(delegate, n), 1)        
}

assert 5 == 2 + 2

Это на самом деле не так хорошо задокументировано, и я планировал разместить пост в блоге на эту тему либо сегодня вечером, либо завтра :).

1 голос
/ 28 мая 2009

Используйте это, чтобы "испортить" плюс метод:

Integer.metaClass.plus {Integer n -> delegate - (-n) - (-1)}
assert 2+2 == 5

Не удивительно, что использование оператора «+» в методе «перегрузка плюс» приведет к StackOverflow, требуется использовать что-то отличное от оператора «+».

Другой механизм: используйте XOR или некоторую магию битового оператора.

С уважением, Peacefulfire

...