Как преобразовать Proc в блок в расширении Ruby C?

StackOverflow https://stackoverflow.com/questions/1241341

  •  12-09-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

Из кирки, с.871 (издание 1.9)

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

Вызывает метод с аргументами-аргументами и блоком блоков.А yield Из этого метода будет вызвать блок с аргументом, который дал доход, и второй аргумент Arg2.

Так что передайте свой Proc объекты как arg2 и определить (*block)() функция, которая просто пересылает переданное значение в Proc's #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);
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top