@NiftみたいなランダムなIDを生成するのって?

現実逃避。

alph[rand(52)].chr + alph[rand(52)].chr + alph[rand(52)].chr

と重複してるのが気になって、指定回数分ブロックの演算結果を足していくメソッドを作ってみた。標準のメソッドでありそうな気がするんだけど思いつかない。

#!/usr/bin/ruby

class Object
  def pile(n=1, &b)
    return b.nil? ? self : (1..n).inject(self) { |r,| r + b.call }
  end
end


if __FILE__ == $0
  p "".pile(3){ alph[rand(alph.size)].chr } + ("%.5s" % rand(100000))
  p "".pile{ alph[rand(alph.size)].chr }
  p "".pile
end

結果は

"ynz46625"
"U"
""

とか。


こういう inject の使い方は前田さんから習いまった。んで、それの主客の転倒みたいな。


追記:
やっぱこっちの方が汎用性高いな。名前はともかく。

#!/usr/bin/ruby

class Object
  def repeat(n=1, &b)
    return b.nil? ? self : (1..n).inject(self) { |r,| b.call(r) }
  end
end


if __FILE__ == $0
  p "".repeat(3){|r| r + alph[rand(alph.size)].chr}+ ("%.5s" % rand(100000))

  p "a".repeat(10){|r| r.succ}
end

apply じゃ関数型言語のと紛れるし、times は取られてるし、iterate もちょっとなぁ。Ruby はリスト(というか配列)を特別視するわけじゃないから apply でいいかも?


追記2:
id:walf443 さん、情報ありがとうございます。すっきりしてますね。
webrick/util.rb:

    RAND_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                 "0123456789" +
                 "abcdefghijklmnopqrstuvwxyz"

    def random_string(len)
      rand_max = RAND_CHARS.size
      ret = ""
      len.times{ ret << RAND_CHARS[rand(rand_max)] }
      ret
    end
    module_function :random_string

eto さんがどっかで言ってた通り、全体的に上品なコードだなぁ。

# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights

ですってよ。