Come faccio a convertire un Proc ad un blocco in estensione Rubino C?
-
12-09-2019 - |
Domanda
Sono Memorizzazione una matrice di procs in un'estensione rubino C e devo passare attraverso e instance_eval ogni proc. Il problema è che instance_eval accetta solo i blocchi, non procs. Questo non è un problema in Ruby dove posso andare semplicemente:
proc_list.each { |my_proc|
@receiver.instance_eval(&my_proc)
}
Comunque non sono sicuro di come fare per questo utilizzando l'API di Ruby C.
Qualcuno ha qualche idea di come potrei fare questo?
Soluzione
Dalla zappa, p. 871 (1.9 edition)
VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE arg2 )
metodo richiama con args argomento e blocco blocco. Un
yield
da quella metodo invocherà blocco con l'argomento dato a cedere e una seconda argomento arg2.
Quindi, passare i vostri oggetti Proc
come arg2
e definire una funzione (*block)()
che appena inoltra il valore passato al metodo Proc
del #call
.
Qualcosa di simile
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);
}
Non ho ancora testato questo codice, ma è coerente con le avvertenze in questo articolo .