简体   繁体   English

如何将Proc转换为Ruby C扩展中的块?

[英]How do I convert a Proc to a block in a Ruby C extension?

I am storing an array of procs in a Ruby C extension and I need to go through and instance_eval each proc. 我在Ruby C扩展中存储了一系列proc,因此我需要遍历每个proc和instance_eval。 The problem is that instance_eval only accepts blocks, not procs. 问题在于instance_eval仅接受块,而不接受proc。 This is not an issue in Ruby where I can simply go: 在Ruby中,这不是我可以简单解决的问题:

proc_list.each { |my_proc|
    @receiver.instance_eval(&my_proc)
}

However I am unsure how to go about this using the Ruby C API. 但是我不确定如何使用Ruby C API进行此操作。

Does anyone have any ideas how I might accomplish this? 有谁知道我将如何实现这一目标?

From the pickaxe, p. 从镐头开始。 871 (1.9 edition) 871(1.9版)

VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE arg2 )

Invokes method with argument args and block block. 调用带有参数args和block block的方法。 A yield from that method will invoke block with the argument given to yield and a second argument arg2. 该方法的yield将调用具有yield的参数和第二个参数arg2的块。

So pass your Proc objects as arg2 and define a (*block)() function that just forwards the passed value to the Proc 's #call method. 因此,将您的Proc对象作为arg2传递,并定义一个(*block)()函数,该函数会将传递的值转发给Proc#call方法。

Something like 就像是

for (i = 0; i < numProcs; i++)
{
  rb_iterate( forwarder, receiver, block, procs[i] );
}

/*...*/

VALUE forwarder(VALUE receiver)
{
  // the block passed to #instance_eval will be the same block passed to forwarder
  return rb_obj_instance_eval(0, NULL, receiver);
}
VALUE block(VALUE proc)
{
  return rb_funcall(proc, rb_intern("call"), 0);
}

I haven't tested this code, but it's consistent with the caveats in this article . 我尚未测试此代码,但这与本文中的警告一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM