passing a block in an extension

C

Charles Mills

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 <ruby.h>
#include <intern.h>

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);
}
 
J

Jeff Mitchell

--- Charles Mills said:
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 <ruby.h>
#include <intern.h>

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);

return rb_yield(ary);
}

void Init_test()
{
rb_define_module_function(rb_mKernel, "my_method", my_method,
0);
}





__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail
 
C

Charles Mills

return rb_yield(ary);
Not exactly what I am after. I was hoping to be able to use the block
passed to "my_method" as a parameter to a call when calling a method
(in this case "each") on a Ruby object (in this case ary) created in
"my_method".
 
C

Charles Mills

return rb_yield(ary);

Not exactly what I am after. I was hoping to be able to use the block
passed to "my_method" when calling a method (in this case "each") on a
Ruby object (in this case ary) created in "my_method".

So the result I am looking for is puts getting called on each element
of ary.
 
S

Sean O'Dell

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 <ruby.h>
#include <intern.h>

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
 
N

nobu.nokada

Hi,

At Wed, 23 Jun 2004 03:22:30 +0900,
Charles Mills wrote in [ruby-talk:104362]:
#include <ruby.h>
#include <intern.h>

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_iterate(rb_each, ary, rb_yield, 0);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top