From: "Berger, Daniel" Date: 2005-06-01T01:45:54+09:00 Subject: Re: Passing a block to rb_funcall > -----Original Message----- > From: nobu.nokada@softhome.net [mailto:nobu.nokada@softhome.net] > Sent: Tuesday, May 31, 2005 9:58 AM > To: ruby-talk ML > Subject: Re: Passing a block to rb_funcall > > > 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 Oops, just wanted to point out (for future googlers) that I'll have to tweak this because if no value is passed for the separator, then args[1] becomes nil. Explicitly passing nil to IO.foreach puts it in paragraph mode, i.e. this code is the equivalent of IO.foreach(path,nil){ ... } if no path separator is specified. I believe this is, yet again, the result of manual argc counting in the underlying C code. It looks like: /* rb_io_s_foreach */ if (argc == 1) { arg.sep = rb_default_rs; } Should instead be: if(NIL_P(arg.sep)) arg.sep = rb_default_rs; That is, unless we *want* nil to mean paragraph mode. I was always under the impression that only "" (an empty string) would force paragraph mode. Regards, Dan