On Fri, 8 Dec 2006, Tim Pease wrote:

> If anyone out there has used the "rb_iterate" function in a Ruby C
> extension, could you please post a simple explanation of (a) how to
> use the function and (b) an explanation of the method signature?
>
>> From eval.c ...
>
> VALUE
> rb_iterate(it_proc, data1, bl_proc, data2)
>   VALUE (*it_proc) _((VALUE)), (*bl_proc)(ANYARGS);
>   VALUE data1, data2;
> {
>   ...
> }
>
>
> I understand that "it_proc" and "bl_proc" are function pointers and
> "data1" and "data2" are the arguments that are passed to each
> function, respectively.  What I don't understand is how all these work
> together to iterate over a collection.
>
> Pointers, tips, tutorials, explanations?

see ext/dbm/dbm.c


at a glance at this

   492 static VALUE
   493 fdbm_replace(obj, other)
   494     VALUE obj, other;
   495 {
   496     fdbm_clear(obj);
   497     rb_iterate(each_pair, other, update_i, obj);
   498     return obj;
   499 }

this

   463 static VALUE
   464 each_pair(obj)
   465     VALUE obj;
   466 {
   467     return rb_funcall(obj, rb_intern("each_pair"), 0, 0);
   468 }


this

   472 static VALUE
   473 update_i(pair, dbm)
   474     VALUE pair, dbm;
   475 {
   476     Check_Type(pair, T_ARRAY);
   477     if (RARRAY(pair)->len < 2) {
   478         rb_raise(rb_eArgError, "pair must be [key, value]");
   479     }
   480     fdbm_store(dbm, RARRAY(pair)->ptr[0], RARRAY(pair)->ptr[1]);
   481     return Qnil;
   482 }


and this

795     rb_define_method(rb_cDBM,"replace", fdbm_replace, 1);


i think we can translate

   497     rb_iterate(each_pair, other, update_i, obj);

which would look like

   dbm.replace other

in ruby

as

   iterate over 'other' via the method 'each_pair' and, for each yielded pair,
   call the method 'update_i' on 'obj'.

at least that what i'm guessing - i have __no__ idea ;-)

regards.


-a
-- 
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion.  -- the dalai lama