Project

General

Profile

Feature #15618 ยป 0001-Implement-Enumerator-Yielder-to_proc.patch

knu (Akinori MUSHA), 02/24/2019 03:14 PM

View differences:

enumerator.c
110 110
static VALUE rb_cLazy;
111 111
static ID id_rewind, id_new, id_to_enum;
112 112
static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
113
static ID id_begin, id_end, id_step, id_exclude_end;
114
static VALUE sym_each, sym_cycle;
113
static ID id_begin, id_end, id_step, id_exclude_end, id_to_proc;
114
static VALUE sym_each, sym_cycle, sym_yield;
115 115

  
116 116
#define id_call idCall
117 117
#define id_each idEach
......
1288 1288
    return obj;
1289 1289
}
1290 1290

  
1291
/*
1292
 * Returns a Proc object that takes an argument and yields it.
1293
 *
1294
 * This method is implemented so that a Yielder object can be directly
1295
 * passed to another method as a block argument.
1296
 *
1297
 *   enum = Enumerator.new { |y|
1298
 *     Dir.glob("*.rb") { |file|
1299
 *       File.open(file) { |f| f.each_line(&y) }
1300
 *     }
1301
 *   }
1302
 */
1303
static VALUE
1304
yielder_to_proc(VALUE obj)
1305
{
1306
    VALUE method = rb_obj_method(obj, sym_yield);
1307

  
1308
    return rb_funcall(method, id_to_proc, 0);
1309
}
1310

  
1291 1311
static VALUE
1292 1312
yielder_yield_i(RB_BLOCK_CALL_FUNC_ARGLIST(obj, memo))
1293 1313
{
......
3380 3400
    rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0);
3381 3401
    rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
3382 3402
    rb_define_method(rb_cYielder, "<<", yielder_yield_push, 1);
3403
    rb_define_method(rb_cYielder, "to_proc", yielder_to_proc, 0);
3383 3404

  
3384 3405
    /* Chain */
3385 3406
    rb_cEnumChain = rb_define_class_under(rb_cEnumerator, "Chain", rb_cEnumerator);
......
3430 3451
    id_end = rb_intern("end");
3431 3452
    id_step = rb_intern("step");
3432 3453
    id_exclude_end = rb_intern("exclude_end");
3454
    id_to_proc = rb_intern("to_proc");
3433 3455
    sym_each = ID2SYM(id_each);
3434 3456
    sym_cycle = ID2SYM(rb_intern("cycle"));
3457
    sym_yield = ID2SYM(rb_intern("yield"));
3435 3458

  
3436 3459
    InitVM(Enumerator);
3437 3460
}
test/ruby/test_enumerator.rb
493 493
    assert_equal([1, 2, 3], y.yield(2, 3))
494 494

  
495 495
    assert_raise(LocalJumpError) { Enumerator::Yielder.new }
496

  
497
    # to_proc (explicit)
498
    a = []
499
    y = Enumerator::Yielder.new {|x| a << x }
500
    b = y.to_proc
501
    assert_kind_of(Proc, b)
502
    assert_equal([1], b.call(1))
503
    assert_equal([1], a)
504

  
505
    # to_proc (implicit)
506
    e = Enumerator.new { |y|
507
      assert_kind_of(Enumerator::Yielder, y)
508
      [1, 2, 3].each(&y)
509
    }
510
    assert_equal([1, 2, 3], e.to_a)
496 511
  end
497 512

  
498 513
  def test_size
499
-