Как преобразовать Proc в блок в расширении Ruby C?
-
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);
}
Я не проверял этот код, но он соответствует предостережениям в Эта статья.