2016-06-17 2 views
0

私はそれの周りに私の頭を包むことはできません。私はruby-doc on enumeratorに相談しようとしましたが、あまり役に立ちませんでした。ルビー-docのからenumerator.newで何をするdo | y |

fib = Enumerator.new do |y| 
    a = b = 1 
    loop do 
    y << a 
    a, b = b, a + b 
    end 
end 

私は理解していない、なぜ私はちょうどfib = Enumerator.newを書くが、私はfib = Enumerator.new do |y|を書くことはできませんか?

どのタイプのオブジェクトがyですか? fib.nextを実行したとき、またはfib.take(5)を実行したときに、yとは何ですか?

答えて

0

私はfib = Enumerator.newと書くことができませんが、fib = Enumerator.new do | y |と書く必要がありますか?

あなたはどちらかを呼び出すnextまたはtake(5)

yがあなたの列挙子を参照するローカルスコープの変数になるまで何も評価しない列挙子を作成しました。基本的に、ブロックdo..endの列挙子を生成し、列挙子に独自のロジックを適用しているため、アクセスされたときには目的の値に評価されます。

1

あなたが使用しているフォームは、値としてyになることができる任意の値になるブロックを引数として受け入れます。

fib.nextが呼び出されると、値yは呼び出し元に「返されます」。あなたの例で分かるように、ブロックはループを呼び出し、各反復の値を計算します。したがって、yは値を累積する配列です。

したがって、fib列挙子のtake(10)を呼び出すと、最初の10個のフィボナッチ数が「生成」されます。次のコールは11番目の "yield"となります。この列挙子は、必要ない場合でも「無限」と見なすことができます。

別の不自然な例:ここでは

concat = Enumerator.new do |c| 
    cat = "concat" 
    loop do 
     c << cat 
     cat += "concat" 
    end 
end 

p concat.take(5) 

は、列挙子は何度も「連結」の文字列を生成します。 Thisは古い記事ですが、列挙子は列挙可能であるため、takeを呼び出すと、このクラスのメソッドを使用できます。

関連する問題