3

Enumerator#each がシーケンスの現在の位置から始まらないことに驚いています。

o = Object.new

def o.each
  yield 1
  yield 2
  yield 3
end

e = o.to_enum
puts e.next
puts e.next
e.each{|x| puts x}
# I expect to see 1,2,3 but I see 1,2,1,2,3
# apparently Enumerator's each (inherited from Enumerable) restarts the sequence!

私はそれを間違っていますか?予想される各動作を持つ別の列挙子 (e から) を構築する方法はありますか?

4

2 に答える 2

3

間違っているわけではありません。それは で定義されたセマンティクスではありませんEnumerator#each。現在の位置から最後まで反復するだけの派生列挙子を作成できます。

class Enumerator
  def enum_the_rest
    Enumerator.new { |y| loop { y << self.next } }
  end
end

o = Object.new
def o.each
  yield 1
  yield 2
  yield 3
end

e = o.to_enum
=> #<Enumerator: ...>
e.next
=> 1
e2 = e.enum_the_rest
=> #<Enumerator: ...>
e2.each { |x| puts x }
=> 2
=> 3

そして、ところで、eachシーケンスを再開せず、常にスパン全体で実行されます。列挙子は、次のnext呼び出しに関連してどこにあるかをまだ知っています。

e3 = o.to_enum
e3.next
=> 1
e3.next
=> 2
e3.map(&:to_s)
=> ["1", "2", "3"]
e3.next
=> 3
于 2013-05-05T19:41:40.353 に答える