New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LocalJumpError: no block given #1553
Comments
Could you link directly to the code and an actual script that shows the issue? |
Sure, sorry, I should have done that right away. Given this C code: #include "localjump.h"
VALUE mLocalJump;
VALUE cLocalJumpTest;
static VALUE
local_jump_init(VALUE self, VALUE value)
{
rb_iv_set(self, "value", value);
return self;
}
static VALUE
int_each_i(VALUE cur, VALUE arg)
{
rb_yield(cur);
return Qnil;
}
static VALUE
local_jump_each(VALUE self)
{
VALUE enumerable = rb_iv_get(self, "value");
if (!rb_block_given_p())
return rb_funcall(enumerable,
rb_intern("enum_for"),
1,
ID2SYM(rb_intern("each")));
if (rb_obj_is_kind_of(enumerable, rb_cArray))
rb_ary_each(enumerable);
else
rb_iterate(rb_each, enumerable, int_each_i, Qnil);
return enumerable;
}
void
Init_localjump(void)
{
mLocalJump = rb_define_module("LocalJump");
cLocalJumpTest = rb_define_class_under(mLocalJump, "Test", rb_cObject);
rb_define_method(cLocalJumpTest, "initialize", local_jump_init, 1);
rb_define_method(cLocalJumpTest, "each", local_jump_each, 0);
} this Ruby code triggers the error: o = Object.new
def o.each
yield 1
yield 2
yield 3
end
result=[]
lj = LocalJump::Test.new(o)
lj.each { |i| result << i }
puts [1, 2, 3] == result The error is triggered in both 1.8 and 1.9 compatibility mode, while it runs and outputs 'true' as expected in CRuby. |
I've also made a mini gem that showcases the behavior. Unfortunately I can't attach it here - please let me know if you're interested and I can publish/send it somewhere. |
Thanks, guys! |
Hi,
I have code where a class can take an arbitrary object responding to each as its value,
and when I call each on the wrapping object, it should actually delegate to the inner object's
each method. Something like this:
o = Object.new
def o.each
yield 1
yield 2
end
val = SomeValue.new(o)
val.each do |e|
puts e
end
I'd expect it to print 1 and 2. The fun part is now that the implementation for delegation happens in C. In the C function for SomeValue#each, I call
rb_iterate(enumerable, rb_each, iter_i, 0);
where iter_i is defined as:
VALUE iter_i(VALUE cur, VALUE arg) { rb_yield(cur); return Qnil; }
In fact, "enumerable" would become what I called o above.
This code works in CRuby 1.9.3, but when I run it on Rubinius master, I get an error message like
Failure/Error: yield 1
LocalJumpError:
no block given
I'm not sure whether this is a bug or whether I'm doing something wrong...
It seems like the block given to val.each is not forwarded to the call on o.each, but I'm not really sure if it is supposed to either.
Thanks in advance,
Martin
The text was updated successfully, but these errors were encountered: