From: Yusuke ENDOH Date: 2009-11-11T22:37:24+09:00 Subject: [ruby-dev:39660] [Bug:trunk] Enumerator.new {|y| y << 1 << 2 << 3 } 遠藤です。 Enumerator.new の中で yielder << 1 << 2 << 3 と書けません。 # OK generator = Enumerator.new do |yielder| yielder << 1 yielder << 2 yielder << 3 end generator.each {|x| p x } #=> 1, 2, 3 # NG generator = Enumerator.new do |yielder| yielder << 1 << 2 << 3 end generator.each {|x| p x } #=> 1 Enumerator::Yielder#<< が {|x| p x } のブロックの戻り値を返すため 変なことになっています。 Yielder#<< は IO 出力のように、列挙したいものを流し込むように使う ものだと思っています。この理解が正しければ、強烈に違和感のある挙動 だと思います。 今 Yielder#<< は Yielder#yield の alias になっていますが、yield は 元の挙動のまま、Yielder#<< だけ常に self を返すようにしてもいいで しょうか。 diff --git a/enumerator.c b/enumerator.c index e341c07..7c50f3d 100644 --- a/enumerator.c +++ b/enumerator.c @@ -1012,6 +1012,13 @@ yielder_yield(VALUE obj, VALUE args) return rb_proc_call(ptr->proc, args); } +/* :nodoc: */ +static VALUE yielder_yield_push(VALUE obj, VALUE args) +{ + yielder_yield(obj, args); + return obj; +} + static VALUE yielder_yield_i(VALUE obj, VALUE memo, int argc, VALUE *argv) { @@ -1228,7 +1235,7 @@ Init_Enumerator(void) rb_define_alloc_func(rb_cYielder, yielder_allocate); rb_define_method(rb_cYielder, "initialize", yielder_initialize, 0); rb_define_method(rb_cYielder, "yield", yielder_yield, -2); - rb_define_method(rb_cYielder, "<<", yielder_yield, -2); + rb_define_method(rb_cYielder, "<<", yielder_yield_push, -2); id_rewind = rb_intern("rewind"); id_each = rb_intern("each"); -- Yusuke ENDOH