Como faço para converter um Proc para um bloco em uma extensão de Ruby C?
-
12-09-2019 - |
Pergunta
Eu sou armazenar um conjunto de procs em uma extensão de Ruby C e eu preciso passar e instance_eval cada proc. O problema é que instance_eval aceita apenas blocos, não procs. Este não é um problema em Ruby onde posso simplesmente ir:
proc_list.each { |my_proc|
@receiver.instance_eval(&my_proc)
}
No entanto estou inseguro como ir sobre isso usando a API de Ruby C.
Alguém tem alguma idéia de como eu poderia fazer isso?
Solução
A partir da picareta, p. 871 (1,9 edição)
VALUE rb_iterate( VALUE (*method)(), VALUE args, VALUE (*block)(), VALUE arg2 )
método invoca com args argumento e bloco bloco. A
yield
de que método irá invocar o bloco com o argumento dado para produzir e um segundo arg2 argumento.
Então, passar o seu Proc
objetos como arg2
e definir uma função (*block)()
que só encaminha o valor passado ao método Proc
do #call
.
Algo 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);
}
Eu não testei este código, mas é consistente com as ressalvas em este artigo .