Comment puis-je convertir un Proc à un bloc dans une extension Ruby C?
-
12-09-2019 - |
Question
je stocke un tableau de procs dans une extension Ruby C et je dois passer par et instance_eval chaque proc. Le problème est que instance_eval accepte que des blocs, non procs. Ce n'est pas un problème dans Ruby où je peux simplement aller:
proc_list.each { |my_proc|
@receiver.instance_eval(&my_proc)
}
Je suis toutefois pas certain comment aller à ce sujet en utilisant l'API Ruby C.
Est-ce que quelqu'un a des idées comment je pourrais y arriver?
La solution
De l'pickaxe, p. 871 (1.9 édition)
VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE arg2 )
méthode Invoque avec args argument et bloc de bloc. A partir de ce
yield
Procédé appellera bloc avec l'argument donné pour donner un deuxième et arg2 argument.
Donc, passez vos objets Proc
comme arg2
et définir une fonction qui transmet (*block)()
juste la valeur passée à la méthode Proc
du #call
.
Quelque chose comme
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);
}
Je ne l'ai pas testé ce code, mais il est compatible avec les mises en garde dans cet article .