diff --git a/struct.c b/struct.c index 7de46980aa..e4c875b5be 100644 --- a/struct.c +++ b/struct.c @@ -860,6 +860,9 @@ rb_struct_inspect(VALUE s) static VALUE rb_struct_to_a(VALUE s) { + if (!rb_method_basic_definition_p(CLASS_OF(s), idEach)) { + return rb_call_super(0, 0); + } return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s)); } @@ -1077,6 +1080,9 @@ rb_struct_select(int argc, VALUE *argv, VALUE s) rb_check_arity(argc, 0, 0); RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size); + if (!rb_method_basic_definition_p(CLASS_OF(s), idEach)) { + return rb_call_super(argc, argv); + } result = rb_ary_new(); for (i = 0; i < RSTRUCT_LEN(s); i++) { if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) { diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb index 384c95f85b..99c3e74a92 100644 --- a/test/ruby/test_struct.rb +++ b/test/ruby/test_struct.rb @@ -393,6 +393,24 @@ def test_new_dupilicate } end + def test_enumerable_methods + klass = @Struct.new(:a) + x = klass.new("test") + assert_equal(["test"], x.to_a) + assert_equal(["test"], x.select { |member| member }) + end + + def test_enumerable_methods_with_overridden_each + klass = @Struct.new(:a) do + def each(&block) + a.each_char(&block) + end + end + x = klass.new("test") + assert_equal(["t", "e", "s", "t",], x.to_a) + assert_equal(["t", "e", "s", "t",], x.select { |member| member }) + end + class TopStruct < Test::Unit::TestCase include TestStruct