Project

General

Profile

Bug #15027 ยป struct_enumerable_fix.patch

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

View differences:

struct.c
1055 1055
    return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
1056 1056
}
1057 1057

  
1058
/*
1059
 *  call-seq:
1060
 *     struct.select {|obj| block }  -> array
1061
 *     struct.select                 -> enumerator
1062
 *
1063
 *  Yields each member value from the struct to the block and returns an Array
1064
 *  containing the member values from the +struct+ for which the given block
1065
 *  returns a true value (equivalent to Enumerable#select).
1066
 *
1067
 *     Lots = Struct.new(:a, :b, :c, :d, :e, :f)
1068
 *     l = Lots.new(11, 22, 33, 44, 55, 66)
1069
 *     l.select {|v| v.even? }   #=> [22, 44, 66]
1070
 */
1071

  
1072
static VALUE
1073
rb_struct_select(int argc, VALUE *argv, VALUE s)
1074
{
1075
    VALUE result;
1076
    long i;
1077

  
1078
    rb_check_arity(argc, 0, 0);
1079
    RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
1080
    result = rb_ary_new();
1081
    for (i = 0; i < RSTRUCT_LEN(s); i++) {
1082
	if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
1083
	    rb_ary_push(result, RSTRUCT_GET(s, i));
1084
	}
1085
    }
1086

  
1087
    return result;
1088
}
1089

  
1090 1058
static VALUE
1091 1059
recursive_equal(VALUE s, VALUE s2, int recur)
1092 1060
{
......
1286 1254

  
1287 1255
    rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
1288 1256
    rb_define_alias(rb_cStruct,  "to_s", "inspect");
1289
    rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
1290 1257
    rb_define_method(rb_cStruct, "to_h", rb_struct_to_h, 0);
1291 1258
    rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
1292 1259
    rb_define_method(rb_cStruct, "size", rb_struct_size, 0);
......
1296 1263
    rb_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
1297 1264
    rb_define_method(rb_cStruct, "[]", rb_struct_aref, 1);
1298 1265
    rb_define_method(rb_cStruct, "[]=", rb_struct_aset, 2);
1299
    rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
1300 1266
    rb_define_method(rb_cStruct, "values_at", rb_struct_values_at, -1);
1301 1267

  
1302 1268
    rb_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
test/ruby/test_struct.rb
393 393
    }
394 394
  end
395 395

  
396
  def test_enumerable_methods
397
    klass = @Struct.new(:a)
398
    x = klass.new("test")
399
    assert_equal(["test"], x.to_a)
400
    assert_equal(["test"], x.select { |member| member })
401
  end
402

  
403
  def test_enumerable_methods_with_overridden_each
404
    klass = @Struct.new(:a) do
405
      def each(&block)
406
        a.each_char(&block)
407
      end
408
    end
409
    x = klass.new("test")
410
    assert_equal(["t", "e", "s", "t",], x.to_a)
411
    assert_equal(["t", "e", "s", "t",], x.select { |member| member })
412
  end
413

  
396 414
  class TopStruct < Test::Unit::TestCase
397 415
    include TestStruct
398 416