2

Java ライブラリと Ruby コードを統合する方法を学んでいて、次の質問に行き着きました。

次のように、Java で実装されたコマンド パターンがあります。

public interface Command {
  public String execute(String param);
}

public class CommandRunner {

  public String run(Command cmd, String param) {
    return cmd.execute(param)+" [this is added by run method]";
  }
}

respond_to? :executeそれをJRubyプログラムにインポートすると、1つのパラメータを持つRubyクラスを実装してCommandRunner.new.run. それは機能し、それは明らかです。

しかし、私はこれを行うこともできます:

def put_through_runner(param, &block)
  CommandRunner.new.run block, param
end

p = put_through_runner "through method" do |param|
  "Cmd implementation in block, param: #{param}"
end

puts p

CommandRunnerメソッドを実装するオブジェクトを Java に渡す代わりに、executeメソッドを実装しないコード ブロックを Java に渡します。そしてそれは機能します:executeメソッドの実装であるかのようにブロックを呼び出します! そんなことがあるものか?ブロックをJavaに渡すとき、JRubyはブロックに対して何をしますか? Ruby で実装した場合CommandRunner、上記のコードは機能しません。

4

1 に答える 1

3

これが機能する理由は、「クロージャー変換」と呼ばれる機能です (こちらのドキュメントを参照してください)。Proc何が起こるかというと、渡したブロックは、オブジェクトで呼び出されたメソッドのブロック内のコードを呼び出すプロキシを使用してオブジェクトに変換されます。

于 2013-11-06T16:36:58.787 に答える