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"

但即使使用谷歌,我也没有找到如何在 Rice 中使用块。我发现的唯一一件事是如何从 C++ 迭代器中定义 ruby​​ each 方法,这当然需要一个块。我想一旦我存储了 proc 对象,这很容易,我只需使用适当的参数调用 ruby​​ 方法“调用”它,但是我如何检查构造函数是否被赋予了一个块,如果是,存储阻塞成一个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 回答