Редактировать: ОК, теперь, когда вы пояснили, что делаете (немного; -))
Другой подход (который я использую для DSL) - это анализ вашегогруппу замыканий для сопоставления с помощью утилиты ClosureToMap, например:
// converts given closure to map method => value pairs (1-d, if you need nested, ask)
class ClosureToMap {
Map map = [:]
ClosureToMap(Closure c) {
c.delegate = this
c.resolveStrategy = Closure.DELEGATE_FIRST
c.each{"$it"()}
}
def methodMissing(String name, args) {
if(!args.size()) return
map[name] = args[0]
}
def propertyMissing(String name) { name }
}
// Pass your closure to the utility and access the generated map
Map map = new ClosureToMap(your-closure-here)?.map
Теперь вы можете выполнять итерацию по карте, возможно, добавляя методы в соответствующий экземпляр MCL.Например, некоторые из моих доменов имеют динамические средства поиска, такие как:
def finders = {
userStatusPaid = { Boolean active = true->
eq {
active "$active"
paid true
}
}
}
Я создаю карту с помощью утилиты ClosureToMap, а затем выполняю итерацию, добавляя ключи карты (методы, такие как «userStatus») и значения (вв этом случае замыкание "eq") для экземпляра домена MCL, делегирование замыкания нашему ORM, например, так:
def injectFinders(Object instance) {
if(instance.hasProperty('finders')) {
Map m = ClosureToMap.new(instance.finders).map
m?.each{ String method, Closure cl->
cl.delegate = instance.orm
cl.resolveStrategy = Closure.DELEGATE_FIRST
instance.orm.metaClass."$method" = cl
}
}
}
Таким образом, в области действия контроллера я могу сделать, скажем:
def actives = Orders.userStatusPaid()
и закрытие "eq" будет делегировать ORM, а не заказам доменов, где возникнет MME.
Поэкспериментируйте с этим, надеюсь, я дал вам несколько идей о том, как решить проблему.В Groovy, если вы не можете сделать это одним способом, попробуйте другой; -)
Удачи!
Оригинал: Ваш missingMethod определен в строковом метаклассе;для того, чтобы он был вызван, вам нужно "someString" .foo ()
Если вы просто вызываете foo () внутри своего замыкания, это завершится неудачей, независимо от используемой стратегии делегирования;т.е. если вы не используете делегат (String), удачи.Например, выполните "" .foo (), и это сработает.
Я также не до конца понимаю проблему, почему у вас не будет доступа к делегату замыкания?Вы устанавливаете делегат замыкания и вызываете замыкание, что означает, что у вас будет доступ к делегату внутри самого замыкания (и вы можете просто делегировать.foo ())