いまどきの Ruby なフィボナッチ数列

Enumerator.produceを使います。

fib = Enumerator.produce([1, 1]) { |a, b| [b, a + b] }.lazy.map(&:first)

#最初の10個
fib.first(10)
#=>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

#数列の100以上3000未満の部分
fib.drop_while { _1 < 100 }.take_while { _1 < 3000 }.force
#=>[144, 233, 377, 610, 987, 1597, 2584]

#1000未満で素数であるもの
require "prime"
fib.select(&:prime?).take_while { _1 < 1000 }.force
#=>[2, 3, 5, 13, 89, 233]

 

追記(12/6)

無駄に便利にしてみました。

module Fib
  Seq = Enumerator.produce([1, 1]) { |a, b| [b, a + b] }.lazy.map(&:first)
  
  class << self
    def method_missing(name, *args, &bk)
      Seq.__send__(name, *args, &bk)
    end
    
    def [](arg)
      case arg
      in Integer => i
        drop(i).first
      in Range => r
        a = r.begin
        if r.end
          b = r.exclude_end? ? r.end - 1 : r.end
          drop(a).take(b - a + 1).force
        else
          drop(a)
        end
      end
    end
  end
end

#最初の10個
Fib.first(10)    #=>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

#最初の5個をそれぞれ2乗した数列
Fib.map { _1 ** 2 }.first(5)    #=>[1, 1, 4, 9, 25]

#(0番始まりで)9番目の値
Fib[9]    #=>55

#(0番始まりで)3番目から9番目までの数列
Fib[3..9]    #=>[3, 5, 8, 13, 21, 34, 55]

#3番めから9-1番目までの数列
Fib[3...9]    #=>[3, 5, 8, 13, 21, 34]

#3番目からの無限数列を10個取ったもの
Fib[3..].first(10)    #=>[3, 5, 8, 13, 21, 34, 55, 89, 144, 233]