Я пишу большой скрипт Groovy, содержащий ряд глобальных свойств и закрытий. Все Closures используются для добавления новых методов к существующим классам, например .:Как вы можете изменить стратегию решения Closure по умолчанию для скрипта Groovy?
myProperty = 'foo'
// ...more script code...
class MyClass {
def myProperty = 'default'
}
// ...more script code...
MyClass.metaClass.evaluate = { ->
myProperty = 'bar'
}
def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "default" instead of "bar"
Моего намерение состоит в закупоривающем myProperty
для обозначения класса делегата myProperty
, а не глобальной. Я нашел несколько способов справиться с этим:
1) Явным разыменовать delegate
внутри крышки:
MyClass.metaClass.evaluate = { ->
delegate.myProperty = 'bar'
}
def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "bar" as desired
2) Установите стратегию решимости закрытия для DELEGATE_ONLY:
def evalClosure = { ->
myProperty = 'bar'
}
evalClosure.resolveStrategy = Closure.DELEGATE_ONLY
MyClass.metaClass.evaluate = evalClosure
def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "bar" as desired
Я бы предпочел использовать подход № 2, чтобы избежать «делегирования» по всему месту в моих закрытиях, но я не хочу устанавливать стратегию разрешения для каждого создаваемого мною замыкания.
Как сказать Groovy использовать стратегию решения DELEGATE_ONLY для всех закрытий по умолчанию? Возможно ли это?
LOL. У меня был второй подход в качестве ответа вчера, но он не предусматривал, полагая, что OP будет говорить «в любом случае я должен использовать« only() »за закрытие, я бы предпочел использовать' clos.resolveStrategy'. Я также попытался использовать '@ Category', наследование и т. Д., Но я всегда получал дефолтную' resolStrategy'. Тогда я убедил себя, я должен ждать, пока @tim_yates просветят нас. :-) – dmahapatro
@dmahapatro хе-хе, вам следует больше доверять своим инстинктам ;-) Я чувствую, что BDKosher будет не нравится ответ, но я не могу придумать другого способа сделать это (это не вариант для класса CompilerConfiguration) –
Точно. Я также думал, что если «ClosureMetaClass» поможет, но, как вы сказали, это не будет. Для меня это было хорошим упражнением для мозга в течение нескольких часов. :-) – dmahapatro