我正在编写Ruby 1.9 C扩展,我想在ruby中执行以下操作:
notifier = Notifier.new
notifier.on 'click' do
puts "clicked!"
end
现在问题在于,在C方法上,我只是"接收"一块,据我所知,它甚至不是一个参数:我只能用rb_yield
打电话。
所以我的问题是:在Ruby 1.9 C扩展上是否有办法将块转换为proc或者其他东西,所以我可以将它存储在我的模块中,并在我想要/需要它时稍后调用它?就像异步回调一样!
我已经使用Procs / lambdas实现了这一点,但是直接使用块语法只是丑陋。
答案 0 :(得分:5)
在Ruby C源代码中,您会在proc.c
:
/*
* call-seq:
* proc { |...| block } -> a_proc
*
* Equivalent to <code>Proc.new</code>.
*/
VALUE
rb_block_proc(void)
{
return proc_new(rb_cProc, FALSE);
}
和Proc.new
执行此操作:
创建绑定到当前上下文的新
Proc
对象。只有在带有附加块的方法中,才可以在没有块的情况下调用Proc::new
,在这种情况下,该块将转换为Proc
对象。
所以你会做这样的事情:
VALUE p = rb_block_proc();
/* and then store `p` somewhere convenient */
然后再调用块/ Proc:
rb_funcall(p, rb_intern("call"), 0);
rb_funcall
几乎是p.send(:call)
的C版本。