6

私はRuby1.9C拡張機能を書いていますが、rubyで次のことを実行したいと思います。

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

これに伴う問題は、Cメソッドでは、ブロックを「受信」するだけであり、私が知る限り、それはパラメーターでさえないということです。で呼び出すことができます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 に答える