From: Sean O'Dell Date: 2004-06-23T04:59:39+09:00 Subject: Re: passing a block in an extension On Tuesday 22 June 2004 11:22, Charles Mills wrote: > I am trying to write a function in C which calls a Ruby function using > the block it was passed when called from Ruby. Below is broken way to > do it, but it explains the idea better. > > $ irb > irb(main):001:0> require 'test' > => true > irb> my_method do |r| > irb* puts r > irb> end > LocalJumpError: no block given > from (irb):4:in `each' > from (irb):4:in `my_method' > from (irb):4 > irb> exit > $ more test.c > #include > #include > > VALUE > my_method(VALUE kernel) > { > VALUE ary = rb_ary_new(); > VALUE str1 = rb_str_new2("hey"); > VALUE str2 = rb_str_new2("hey you"); > rb_ary_push(ary, str1); > rb_ary_push(ary, str2); > > return rb_funcall(ary, rb_intern("each"), 0, 0); > } > > void Init_test() > { > rb_define_module_function(rb_mKernel, "my_method", my_method, > 0); > } Look at rb_scan_args in http://www.rubycentral.com/book/ext_ruby.html. VALUE my_method(int argc, VALUE *argv, VALUE self) { VALUE block = Qnil; VALUE ary = rb_ary_new(); VALUE str1 = rb_str_new2("hey"); VALUE str2 = rb_str_new2("hey you"); rb_scan_args(argc, argv, "&", &block); rb_ary_push(ary, str1); rb_ary_push(ary, str2); return rb_funcall(ary, rb_intern("each"), 1, block); } rb_define_method(rb_cKernel, "my_method", my_method, -1); I'm sure this code won't work right out of the gate, but it should be close to what you're after. Sean O'Dell