Bug #2356
closedEnumerator.new {|y| y << 1 << 2 << 3 }
Description
=begin
遠藤です。
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 mame@tsg.ne.jp
=end