Ruby 1.9.2 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Enumeratorクラス

class Enumerator

クラスの継承リスト: Enumerator < Enumerable < Object < Kernel < BasicObject

Abstract

each 以外のメソッドにも Enumerable の機能を提供するためのラッパークラスです。 また、外部イテレータとしても使えます。

Enumerable モジュールは、 Module#include 先のクラスが持つ each メソッドを元に様々なメソッドを提供します。 例えば Array#map は Array#each の繰り返しを元にして定義されます。 Enumerator を介することにより String#each_byte のような 異なる名前のイテレータについても each と同様に Enumerable の機能を利用できます。

Enumerator を生成するには Enumerator.new あるいは Object#to_enum, Object#enum_for を利用します。 また、一部のイテレータはブロックを渡さずに呼び出すと繰り返しを実行する代わりに enumerator を生成して返します。

注意

外部イテレータとしての機能は Fiber を用いて実装されているため Fiber と同じ制限があります。 例えば以下のようなスレッドをまたいだ呼び出しはエラーになります。

a = nil
Thread.new do
  a = [1, 2, 3].each
  a.next
end.join

p a.next
#=> t.rb:7:in `next': fiber called across threads (FiberError)
        from t.rb:7:in `<main>'

特異メソッド

new(obj, method = :each, *args) -> Enumerator

オブジェクト obj について、 each の代わりに method という 名前のメソッドを使って繰り返すオブジェクトを生成して返します。 args を指定すると、 method の呼び出し時に渡されます。

[PARAM] obj:
イテレータメソッドのレシーバとなるオブジェクト
[PARAM] method:
イテレータメソッドの名前を表すシンボルまたは文字列
[PARAM] args:
イテレータメソッドの呼び出しに渡す任意個の引数

例:

str = "xyz"

enum = Enumerator.new(str, :each_byte)
p enum.map {|b| '%02x' % b }   # => ["78", "79", "7a"]

インスタンスメソッド

each {...} -> object

生成時のパラメータに従ってブロックを繰り返します。 生成時に指定したイテレータの戻り値をそのまま返します。

例:

str = "Yet Another Ruby Hacker"

enum = Enumerator.new(str, :scan, /\w+/)
enum.each {|word| p word }              # => "Yet"
                                        #    "Another"
                                        #    "Ruby"
                                        #    "Hacker"

str.scan(/\w+/) {|word| p word }        # => "Yet"
                                        #    "Another"
                                        #    "Ruby"
                                        #    "Hacker"
next -> object

「次」のオブジェクトを返します。

現在までの列挙状態に応じて「次」のオブジェクトを返し、列挙状態を1つ分進めます。 列挙が既に最後へ到達している場合は、列挙状態を最初まで巻き戻すとともに StopIteration 例外を発生します。

next メソッドによる外部列挙の状態は他のイテレータメソッドによる 内部列挙には影響を与えません。 ただし、 IO#each_line のようにおおもとの列挙メカニズムが副作用を 伴っている場合には影響があり得ます。

[EXCEPTION] StopIteration:
列挙状態が既に最後へ到達しているとき

[SEE_ALSO] Enumerator#rewind

例1:

str = "xyz"
enum = str.each_byte

str.bytesize.times do
  puts enum.next
end
    # => 120
    #    121
    #    122

例2:

str = "xyz"
enum = str.each_byte

begin
  puts enum.next while true
rescue StopIteration
  puts "iteration reached at end"
  puts enum.next
end
    # => 120
    #    121
    #    122
    #    iteration reached at end
    #    120

例3: Kernel.#loop は StopIteration を捕捉します。

str = "xyz"
enum = str.each_byte
loop do
  puts enum.next
end
    # => 120
    #    121
    #    122
rewind -> self

列挙状態を巻き戻します。

next メソッドによる外部列挙の状態を最初まで巻き戻します。 self を返します。

内包するオブジェクトが rewind メソッドを持つとき(respond_to?(:rewind) に 真を返すとき) は、その rewind メソッドを呼び出します。

[SEE_ALSO] Enumerator#next

例:

str = "xyz"
enum = str.each_byte

p enum.next # => 120
p enum.next # => 121
enum.rewind
p enum.next # => 120
to_splat -> Array

この enumerator を多重代入などのための配列に変換します。

with_index(offset = 0) {|(*args), idx| ... } -> object
with_index(offset = 0) -> Enumerator

生成時のパラメータに従って、要素にインデックスを添えて繰り返します。 インデックスは offset から始まります。

ブロックを指定した場合の戻り値は生成時に指定したレシーバ自身です。

例:

str = "xyz"

enum = Enumerator.new(str, :each_byte)
enum.with_index {|byte, idx| p [byte, idx] }
    # => [120, 0]
    #    [121, 1]
    #    [122, 2]

require "stringio"
StringIO.new("foo|bar|baz").each("|").with_index(1) {|s, i| p [s, i] }
    # => ["foo|", 0]
    #    ["bar|", 1]
    #    ["baz", 2]

生成時のパラメータに従って、要素にインデックスを添えてブロックを繰り返します。 インデックスは 0 から始まります。 Enumeartor#with_index は offset 引数を受け取りますが、 each_with_index は受け取りません (引数はイテレータメソッドにそのまま渡されます)。

with_object(obj) -> Enumerator
with_object(obj) {|(*args), memo_obj| ... } -> object

[SEE_ALSO] Enumerable#each_with_object

Methods

Classes