任意の階層だけ繰り返しをネストするメソッド(Ruby) -- 改訂版

Array#nest_loop で、Integer#times の多重ネスト版です。配列にループ回数を入れて呼び出します。わかり切った多重ループを書くのが面倒なときに役立ちます。野良 Gem 'utils' に入っています(参照)。
 

[4, 2, 3].nest_loop do |i, j, k|
  print "#{[i, j, k]} "
end
#=>
[0, 0, 0] [0, 0, 1] [0, 0, 2]
[0, 1, 0] [0, 1, 1] [0, 1, 2]
[1, 0, 0] [1, 0, 1] [1, 0, 2]
[1, 1, 0] [1, 1, 1] [1, 1, 2]
[2, 0, 0] [2, 0, 1] [2, 0, 2]
[2, 1, 0] [2, 1, 1] [2, 1, 2]
[3, 0, 0] [3, 0, 1] [3, 0, 2]
[3, 1, 0] [3, 1, 1] [3, 1, 2]

 
for in 文を使って実装しているので、self の配列の中には範囲演算子や配列、ハッシュなどを使うことができます。

ar = []
[2..6, 2, ["a", "b"]].nest_loop {|i| ar << i}
p ar

#=>[[2, 0, "a"], [2, 0, "b"], [2, 1, "a"], [2, 1, "b"], [3, 0, "a"], [3, 0, "b"],
#   [3, 1, "a"], [3, 1, "b"], [4, 0, "a"], [4, 0, "b"], [4, 1, "a"], [4, 1, "b"],
#   [5, 0, "a"], [5, 0, "b"], [5, 1, "a"], [5, 1, "b"], [6, 0, "a"], [6, 0, "b"],
#   [6, 1, "a"], [6, 1, "b"]]



本体のコードです。
nest_loop.rb

class Array
  def nest_loop(arg = [], &bk)
    check = lambda do |obj|
      return 0...obj if (c = obj.class) == Bignum or c == Integer or c == Fixnum
      obj
    end
    
    ar = dup
    for i in check.call(ar.shift)
      if ar.empty?
        yield(arg + [i])
      else
        ar.nest_loop(arg.push(i), &bk)
        arg.pop
      end
    end
    self
  end
end