0

RubyからGroovyに小さなコードを移植したいのですが、これで行き詰まります。

def given(array,closure) {
    closure.delegate = array
    closure()
}

given([1,2,3,4]) {
   findAll { it > 4}
}

今、それはこのメッセージで死にます:

Exception thrown: Cannot compare ConsoleScript0$_run_closure1 with value 'ConsoleScript0$_run_closure1@1e6743e' and java.lang.Integer with value '4'

クロージャのデリゲートを配列に設定しようとしましたが、findAllメソッドでは、配列の実際のアイテムではなく、クロージャを表しているようです。私もこのようにクロージャーを実行しようとしました:

array.with {
   closure(array)
}

しかし、私はまだそれを機能させることができませんでした。何がうまくいくかについて何か考えはありますか?Rubyに相当するのinstance_evalは、配列のコンテキストでのクロージャーです。

編集:Mykolaのコードを実行すると、次の出力が生成されました:

given [1, 2, 3, 4]
class Demo$_main_closure1
2
Exception thrown: Cannot compare Demo$_main_closure1 with value 'Demo$_main_closure1@fe53cf' and java.lang.Integer with value '2'

groovy.lang.GroovyRuntimeException: Cannot compare Demo$_main_closure1 with value 'Demo$_main_closure1@fe53cf' and java.lang.Integer with value '2'

    at Demo$_main_closure1_closure2.doCall(ConsoleScript3:15)

    at Demo$_main_closure1.doCall(ConsoleScript3:15)

    at Demo$_main_closure1.doCall(ConsoleScript3)

    at Demo.given(ConsoleScript3:28)

    at Demo$given.callStatic(Unknown Source)

    at Demo.main(ConsoleScript3:12)

Groovy1.6.5を実行しています。

4

4 に答える 4

1

この場合、委譲オブジェクトは forEach メソッドを持たない java.util.ArrayList オブジェクトです。

それにもかかわらず、このクラスの Groovy ラッパーにはこのメソッドがありますが、ここでは使用されていません (これはバグである可能性があります)。

を使用してこれを回避できますdelegate.forEach()。これはあなたが考えている DSL を壊していることはわかりますが、一歩近づくことになるかもしれません。

次のコードは私にとってはうまくいきます:

def given(array,closure) {
    closure.delegate = array
    closure()
}

given([1,2,3,4]) {
   delegate.findAll { it > 4}
}
于 2009-11-16T19:57:08.137 に答える
0

試す:

array.with(closure)

または、構文を保持したい場合:

def given(array,closure) {
    array.with(closure)
}
于 2009-12-28T22:14:01.117 に答える