編集:
OK、あなたが何をしているのかを明確にしたので(やや;--))
別のアプローチ (私が 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」クロージャーは、MME が発生するドメイン Orders ではなく、ORM に委任されます。
うまくいけば、問題を解決する方法についていくつかのアイデアを提供できます。Groovy では、ある方法でそれができない場合は、別の方法を試してください ;--)
幸運を!
オリジナル:
missingMethod は文字列メタクラスで定義されています。それを呼び出すには、「someString」.foo() が必要です。
クロージャー内で単に foo() を単独で呼び出すと、使用されている委譲戦略に関係なく、失敗します。つまり、(String) デリゲートを使用しない場合は、幸運を祈ります。適切な例として、 "".foo() を実行すると機能します。
私も問題を完全には理解していません。クロージャーのデリゲートにアクセスできないのはなぜですか? クロージャーのデリゲートを設定していて、クロージャーを呼び出します。つまり、クロージャー自体のデリゲートにアクセスできます (そして、delegate.foo() だけが可能です)。