1

現在作成中の C++ ライブラリの Ruby インターフェイスを作成しています。C++ ライブラリは、FibonacciHeap などの比較関数に基づくいくつかのデータ構造を提供します。ruby 比較関数を使用すると問題なく動作します。つまり、次の Ruby コードが動作します。

f = FibonacciHeap.new
f.push(24)
f.push(2)
f.push(89)
raise unless f.top == 2

しかし、たとえば次のように、ユーザーが独自の比較機能を提供できるようにしたいと思います。

f = FibonacciHeap.new { |a, b| a.length <=> b.length }
f.push("asdf")
f.push("a")
f.push("adsfdsafdsaf")
raise unless f.top == "a"

しかし、Google を使用しても、Rice でブロックを使用する方法がわかりませんでした。私が見つけた唯一のことは、もちろんブロックを取る C++ イテレータからルビの each メソッドを定義する方法です。proc オブジェクトを格納したらすぐに、それは簡単です。適切な引数を使用して ruby​​ メソッド「call」を呼び出すだけですが、コンストラクターにブロックが与えられているかどうかを確認するにはどうすればよいですか。 proc オブジェクトにブロックしますか?

ブロックが取る引数の数を確認できればさらに良いでしょうが、これが可能かどうかはわかりませんが、ユーザーは単純なケースで次のようなものを提供できます

f = FibonacciHeap.new { |a| a.length }

機能を提供する完全な柔軟性を必要としない場合a <=> b

4

1 に答える 1

2

C コードでは、次を呼び出すことができます。

rb_yield(value);

Rice コードでは、以下を使用できます。

Rice::protect(rb_yield, value);

(Rice::protect は通常の C++ 例外動作を保証します)。

これが、Rice::Module::define_iterator が ruby​​ コードに譲る方法です。

于 2013-05-23T17:16:40.367 に答える