を読みながら復習をしていたのですが、Ruby 2.0で導入されたEnumerable#lazyを試してみたくなったので少し脱線してみました。
-
- fibonacci.rb
# -*- coding: utf-8 -*- class Fibonacci include Enumerable def each return to_enum unless block_given? a, b = 0, 1 loop do yield b a, b = b, a + b end end end if $0 == __FILE__ @fib = Fibonacci.new puts "(実験:1) フィボナッチ数列の最初10項を得る。" # lazy有り、なしに関わらず動作 p @fib.lazy.first(10) p @fib.first(10) puts "(実験:2) フィボナッチ数列の第6〜10項を得る。" # lazy無しだと無限ループ p @fib.lazy.drop(5).first(5) # p @fib.drop(5).first(5) puts "(実験:3) フィボナッチ数列の100以上1000未満の数値を得る。" # lazy無しだと無限ループ p @fib.lazy.drop_while{|e| e < 100}.take_while{|e| e < 1000}.to_a # p @fib.drop_while{|e| e < 100}.take_while{|e| e < 1000}.to_a end
-
- 実行結果
$ ruby fibonacci.rb (実験:1) フィボナッチ数列の最初10項を得る。 [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] (実験:2) フィボナッチ数列の第6〜10項を得る。 [8, 13, 21, 34, 55] (実験:3) フィボナッチ数列の100以上1000未満の数値を得る。 [144, 233, 377, 610, 987]
(実験:2)と(実験:3)では、Enumerable#lazyメソッドを付けないと、Enumerable#dropとEnumerable#drop_whileが残りの要素を配列として返そうと無限ループに入ってしまい、いつまでたっても結果が出力されないのだと思います。