Как мне преобразовать Proc в блок в расширении Ruby C? - PullRequest
1 голос
/ 07 августа 2009

Я храню массив процедур в расширении Ruby C, и мне нужно пройти и instance_eval каждого процесса. Проблема в том, что instance_eval принимает только блоки, а не процы. Это не проблема в Ruby, куда я могу просто пойти:

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

Однако я не уверен, как это сделать, используя Ruby C API.

У кого-нибудь есть идеи, как мне это сделать?

1 Ответ

1 голос
/ 07 августа 2009

Из кирки, стр. 871 (1,9 издание)

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

Вызывает метод с аргументами аргументов и блоком блока. A yield от этого метод вызовет блок с аргументом, заданным для yield, и вторым аргумент arg2.

Передайте объекты Proc как arg2 и определите функцию (*block)(), которая просто перенаправляет переданное значение в метод Proc #call.

Что-то вроде

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);
}

Я не тестировал этот код, но он соответствует предостережениям в этой статье .

...