Passing a block to rb_funcall

Hi all,

I've seen some other threads on this subject, but none that quite
answered my question. I'm trying to pass a variable number of
arguments and a block to a class method from within an instance method.
In Ruby it looks like this:

# 'self' is a string
def my_method(*args, &block)
   IO.foreach(self, *args, &block)
end

In C, I was trying something like this:

static VALUE my_method(int argc, VALUE* argv, VALUE self){
   VALUE rbSep, rbBlock;
   rb_scan_args(argc, argv, "01&", &rbSep, &rbBlock);

   return rb_funcall(rb_cIO, rb_intern("foreach"), 3, self, rbSep,
rbBlock);
}

That doesn't work, however. I've tried various combinations of arrays,
and rb_funcall2, but I haven't had any luck.

I've seen some mention of rb_iterate, but I wasn't sure how to apply it
here.

Any ideas?

Regards,

Dan

I've seen some mention of rb_iterate, but I wasn't sure how to apply it
here.

From plruby

static VALUE
pl_each(tmp)
    VALUE *tmp;
{
    return rb_funcall2(tmp[0], (ID)tmp[1], (int)tmp[2], (VALUE *)tmp[3]);
}
/* ... */

    if (rb_block_given_p()) {
        VALUE tmp[4];

        tmp[0] = obj;
        tmp[1] = (VALUE)id;
        tmp[2] = (VALUE)argc;
        tmp[3] = (VALUE)argv;
        return rb_iterate((VALUE(*)(VALUE))pl_each, (VALUE)tmp, rb_yield, 0);
    }

/* ... */

Guy Decoux

Hi,

At Wed, 1 Jun 2005 00:35:22 +0900,
Daniel Berger wrote in [ruby-talk:144097]:

I've seen some mention of rb_iterate, but I wasn't sure how to apply it
here.

static VALUE
call_foreach(VALUE args)
{
    return rb_funcall2(rb_cIO, rb_intern("foreach"), 2, (VALUE *)args);
}

static VALUE
yield_block(VALUE val, VALUE block)
{
    return rb_funcall2(block, rb_intern("call"), 1, &val);
}

static VALUE
my_method(int argc, VALUE* argv, VALUE self)
{
    VALUE args[2], block;

    rb_scan_args(argc, argv, "01&", &args[1], &block);
    args[0] = self;

    return rb_iterate(call_foreach, (VALUE)args, yield_block, block);
}

···

--
Nobu Nakada