我正在为我正在编写的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 ++迭代器中定义ruby每个方法,当然这需要一个块。我想一旦我存储了proc对象,就很容易了,我只是用适当的参数调用ruby方法“call”,但是如何检查构造函数是否被赋予一个块,如果是,则存储阻止进入proc对象?
如果我可以检查块占用的参数数量,那会更好,但我不知道这是否可行,但是用户可以在简单的情况下提供类似
的内容f = FibonacciHeap.new { |a| a.length }
如果他不需要提供a <=> b
功能的充分灵活性。
答案 0 :(得分:2)
在C代码中,您可以调用:
rb_yield(value);
在Rice代码中,您可以使用:
Rice::protect(rb_yield, value);
(Rice :: protect确保正常的C ++异常行为)。
这就是Rice :: Module :: define_iterator如何屈服于ruby代码。