概要
RubyのArray#cycleメソッドは、配列内の要素を一定回数、あるいは無限に循環し、指定したブロックを実行するためのメソッド。例えば[1,2,3]の配列に対してcycleメソッドを用いると、1,2,3,1,2,3,1,2,3,1,2,3…と、配列の要素を循環して処理を行うことができる。
riによるドキュメント
$ ri Array#cycle = Array#cycle (from ruby core) ------------------------------------------------------------------------------ ary.cycle(n=nil) { |obj| block } -> nil ary.cycle(n=nil) -> Enumerator ------------------------------------------------------------------------------ Calls the given block for each element n times or forever if nil is given. Does nothing if a non-positive number is given or the array is empty. Returns nil if the loop has finished without getting interrupted. If no block is given, an Enumerator is returned instead. a = ["a", "b", "c"] a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever. a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
循環回数を指定する場合
cycleメソッドの引数で指定した回数、配列を巡回しながらブロックを実行する。戻り値は必ずnilになる。
irb(main):001:0> [1,2,3].cycle(3) {|n| p n } 1 2 3 1 2 3 1 2 3 => nil
循環回数を指定しない場合
cycleメソッドの引数を指定しない、あるいはnilを明示的に指定した場合、配列を無限に巡回する。
当然無限ループになるので、sleepを挟んで出力すると、1秒ごとに1要素、永遠に出力し続ける。
irb(main):002:0* [1,2,3].cycle {|n| p n; sleep 1} 1 2 3 1 2 3 1 2 3 (以下省略)
0以下を指定した場合
cycleメソッドの引数に0以下を指定した場合、ブロックは一度も呼び出されない。
irb(main):013:0* [1,2,3].cycle(0) {|n| p n } => nil irb(main):014:0> [1,2,3].cycle(-1) {|n| p n } => nil
ブロックを指定しない場合
cycleメソッドのブロックを指定しない場合、cycleメソッドはEnumeratorオブジェクトを戻すので遅延評価できる。
irb(main):028:0* enum = [1,2,3].cycle => #<Enumerator: [1, 2, 3]:cycle> irb(main):029:0> enum.first(10) => [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]