Wie konvertiere ich einen Proc zu einem Block in einer Erweiterung Ruby-C?
-
12-09-2019 - |
Frage
ich eine Reihe von Procs in einer Ruby-C-Erweiterung an Speicherung und ich brauche durch und instance_eval jeden proc zu gehen. Das Problem ist, dass instance_eval blockiert nur akzeptiert, nicht Procs. Dies ist kein Problem in Ruby, wo ich einfach gehen kann:
proc_list.each { |my_proc|
@receiver.instance_eval(&my_proc)
}
Doch ich bin nicht sicher, wie um dies zu dem Ruby-C-API.
Hat jemand irgendwelche Ideen, wie ich dies erreichen könnte?
Lösung
Von der Picke, p. 871 (1.9 edition)
VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE arg2 )
Invokes Methode mit dem Argument args und Block Block. A
yield
aus, dass Methode Block mit dem Argument gegeben aufrufen zu ergeben, und eine zweite Argument arg2.
So Ihre Proc
Objekte als arg2
passieren und eine (*block)()
Funktion definieren, die den übergebenen Wert auf die Proc
des #call
Methode nur weiterleitet.
So etwas wie
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);
}
Ich habe diesen Code nicht getestet, aber es ist im Einklang mit den Einschränkungen in dieser Artikel .