2017-07-20 14 views
1

Enumeratorのインスタンスは、内部状態をどのように追跡しますか?例えば、次のコードを取る:Enumeratorオブジェクトはどのように状態を把握していますか?

例えば eachとしてイテレータメソッドが enumに呼び出され
enum = Enumerator.new do |yielder| 
    yielder << 1 
    yielder << 2 
    yielder << 3 
end 

puts enum.next # => 1 
puts enum.next # => 2 
enum.rewind # start again 
puts enum.next # => 1 

は、一度yielder#<<(又はyielder#yield)へのすべての呼に対してeachに与えられたブロックを実行します。

私が理解しようとしているのは、Rubyがnextをどのように動作させるかです。 nextの値はどのように覚えていますか?どうすれば最初のものに戻るrewindnextがRubyでどのように動作するかの基本的な実装をコード化する場合、どうすればよいでしょうか?

+1

次のようになります。https://github.com/rubinius/rubinius/blob/master/core/enumerator.rb –

+1

繊維/コルーチン。 –

答えて

2

列挙子は、実行を内部的に中断し、呼び出し元に制御を渡します。セルジオ氏の言うとおり、それは糸ベースよりも細かい実行単位であるファイバーベースです。

繊維を使用すると、この種のものに行うことができ:

def eat_more_fiber 
    puts "In" 
    Fiber.yield 
    puts "Out" 
end 

f = Fiber.new do 
    eat_more_fiber 
end 

f.resume 
# Prints "In" 
f.resume 
# Prints "Out" 

注最初resume呼制御が戻ってコードのブロックになった後ということ。

+0

'Enumerator#rewind'はどうでしょうか?どのように最初のアイテムに巻き戻されますか? –

+2

@AsadMoosvi:ソースコードを読んでください。すべての答えがそこにあります。ヒント:ブロックを使用して、ヤイヤーを再初期化するだけです。新たに開始します。 –