From: "knu (Akinori MUSHA)" Date: 2012-12-02T22:29:13+09:00 Subject: [ruby-dev:46686] [Ruby 1.8 - Bug #7493] ブロックを渡された場合最初の1要素のみを返すEnumeratorに対してnextを送り続けると、2度目にStopIteration例外が発生する Issue #7493 has been updated by knu (Akinori MUSHA). あと、nextが割り込む位置も1.8と1.9以降では違っています。 破壊的なメソッドを例に取ると分かりやすいですが、 a=[1,2,3] e=a.map! p e.next #=> 1 p e.next #=> 2 p a #=> [nil, nil, 3] (1.8) [nil, 2, 3] (1.9+) と、1.8ではnextで値が返ってくるのはyieldによるブロック呼出が終了した後(というか次のブロック呼出があった時)ですが、 1.9以降では元のメソッドがyieldした直後のタイミングで値が返って来、次のnextで元のメソッドに制御が戻るようになっています。 (1.9以降の挙動が望ましいと思います) ---------------------------------------- Bug #7493: ブロックを渡された場合最初の1要素のみを返すEnumeratorに対してnextを送り続けると、2度目にStopIteration例外が発生する https://bugs.ruby-lang.org/issues/7493#change-34317 Author: kachick (Kenichi Kamiya) Status: Closed Priority: Normal Assignee: Category: Target version: Ruby 1.8.7 ruby -v: ruby 1.8.7 (2012-10-12 patchlevel 371) [x86_64-linux] 「ブロック付きで動かした場合、最初に見つかった1要素のみを返すメソッド」からEnumeratorを作ると、 2度目のnextでStopIteration例外を返すようです。 思い至った限りで確認したメソッドは、以下の物です。 * Array#index * Array#find_index * Array#rindex * Enumerable#detect * Enumerable#find これは、1.8.7と1.9間の仕様に於ける差異と考えた方が良いのでしょうか? 生成されたEnumeratorに対してto_aを送ると全要素を含むArrayが返る事から、 1.8.7に於いても全要素走査出来る方が自然では無いかと感じました。 # to_aとの差異は、dbussinkの指摘で気づくことが出来ました。 # https://github.com/rubinius/rubinius/pull/2063#issuecomment-10881875 array = [:a, :b, :c] index_enum = array.index index_enum.to_a #=> [:a, :b, :c] index_enum.next #=> :a index_enum.next #=> StopIteration: iteration reached at end -- http://bugs.ruby-lang.org/