Project

General

Profile

Bug #15027 » struct_enumerable_fix.patch

bruno (Bruno Sutic), 08/25/2018 05:29 PM

View differences:

struct.c
return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
}
/*
* call-seq:
* struct.select {|obj| block } -> array
* struct.select -> enumerator
*
* Yields each member value from the struct to the block and returns an Array
* containing the member values from the +struct+ for which the given block
* returns a true value (equivalent to Enumerable#select).
*
* Lots = Struct.new(:a, :b, :c, :d, :e, :f)
* l = Lots.new(11, 22, 33, 44, 55, 66)
* l.select {|v| v.even? } #=> [22, 44, 66]
*/
static VALUE
rb_struct_select(int argc, VALUE *argv, VALUE s)
{
VALUE result;
long i;
rb_check_arity(argc, 0, 0);
RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
result = rb_ary_new();
for (i = 0; i < RSTRUCT_LEN(s); i++) {
if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
rb_ary_push(result, RSTRUCT_GET(s, i));
}
}
return result;
}
static VALUE
recursive_equal(VALUE s, VALUE s2, int recur)
{
......
rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
rb_define_alias(rb_cStruct, "to_s", "inspect");
rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
rb_define_method(rb_cStruct, "to_h", rb_struct_to_h, 0);
rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
rb_define_method(rb_cStruct, "size", rb_struct_size, 0);
......
rb_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
rb_define_method(rb_cStruct, "[]", rb_struct_aref, 1);
rb_define_method(rb_cStruct, "[]=", rb_struct_aset, 2);
rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
rb_define_method(rb_cStruct, "values_at", rb_struct_values_at, -1);
rb_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
test/ruby/test_struct.rb
}
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
(1-1/2)