¿Cómo se convierte un Proc a un bloque en una extensión de Ruby C?
-
12-09-2019 - |
Pregunta
Estoy almacenando una serie de procsos en una extensión de Ruby C y tengo que ir a través y instance_eval cada proc. El problema es que sólo acepta instance_eval bloques, no procsos. Este no es un problema en Ruby donde yo puedo ir simplemente:
proc_list.each { |my_proc|
@receiver.instance_eval(&my_proc)
}
Sin embargo, estoy seguro de cómo hacer esto utilizando la API de Ruby C.
¿Alguien tiene alguna idea de cómo podría lograr esto?
Solución
A partir de la piqueta, p. 871 (1.9 edición)
VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE arg2 )
método invoca con el argumento args y bloque de bloque. A partir de ese
yield
método invocará bloque con el argumento dado para producir y una segunda arg2 argumento.
Así que pasar sus objetos Proc
como arg2
y definir una función (*block)()
que simplemente reenvía el valor pasado al método Proc
del #call
.
Algo así como
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);
}
No he probado este código, pero es consistente con las advertencias en este artículo .