6

我正在编写一个 Ruby 1.9 C 扩展,我想在 ruby​​ 中执行以下操作:

notifier = Notifier.new
notifier.on 'click' do
  puts "clicked!"
end

现在的问题是,在 C 方法上,我只“接收”一个块,据我所知,它甚至不是一个参数:我只能用 with 调用rb_yield

所以我的问题是:Ruby 1.9 C 扩展上有没有办法将块转换为 proc 或其他东西,所以我可以将它存储在我的模块中,并在以后需要时调用它?就像一个异步回调!

我已经用 Procs/lambdas 实现了这个,但是不直接使用块语法实在是太丑了。

4

1 回答 1

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 */

然后稍后,调用块/过程:

rb_funcall(p, rb_intern("call"), 0);

rb_funcall几乎是 C 版本的p.send(:call).

于 2012-01-18T01:59:45.470 回答