From: ts Date: 2002-12-01T02:09:49+09:00 Subject: Re: 'C' based iterators >>>>> "S" == Squidster writes: S> 1. rb_iter_break() is the equvalent of "break", what is the equivalent S> of "next"? Well, you can call rb_jump_tag() if you hardcode the value of TAG_NEXT, the best is just to do nothing :-)) S> 2. Scoping tricks S> S> bar = nil S> foo.each { |bar| S> next if bar.capacity < size S> break S> } S> S> In Ruby, I can do scoping tricks as above, so that I get the value of S> bar if the test fails outside of the block. How the heck can I do that S> in 'C'? Well, to write the same in C you use rb_iterate(). From README.EXT VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2) Calls the function func1, supplying func2 as the block. func1 will be called with the argument arg1. func2 receives the value from yield as the first argument, arg2 as the second argument. For example pigeon% cat a.c #include static VALUE a_iter(i, j) VALUE i, *j; { *j = i; if (TYPE(i) != T_ARRAY || RARRAY(i)->len < 3) { rb_iter_break(); } /* this is a next */ return Qnil; } static VALUE a_uu(obj) VALUE obj; { VALUE a = Qnil; rb_iterate(rb_each, obj, a_iter, (VALUE)&a); rb_p(a); return obj; } void Init_a() { rb_define_method(rb_cArray, "uu", a_uu, 0); } pigeon% pigeon% ruby -ra -e '[[1,2], 1].uu' [1, 2] pigeon% pigeon% ruby -ra -e '[[1,2, 3], 1, [1,2,4]].uu' 1 pigeon% pigeon% ruby -ra -e '[[1,2, 3], [1,2,4]].uu' [1, 2, 4] pigeon% Guy Decoux