Scalaでmultipart/form-dataのバウンダリ文字列生成
multipart/form-dataでデータをアップロードする必要が出てきたのでScalaでこりこり書き始めた。
各パートの切れ目を表すboundary文字列を生成するプログラムとしてランダム文字列の生成を見つけた。
以下ソースコード引用。
private String generateBoundary() { String chars = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; Random rand = new Random(); String boundary = ""; for (int i = 0; i < 40; i++) { int r = rand.nextInt(chars.length()); boundary += chars.substring(r, r + 1); } return "---------------------------" + boundary; }
これをほぼそのまま移してもScalaで動くんだが、せっかくなので多少関数型っぽくする。
private def generateBoundary :String = { val chars = (('0' to '9') ++ ('a' to 'z') ++ ('A' to 'Z' )).mkString + "-_" val rand = new scala.util.Random "----------" + (for( i <- 0 until 40 ) yield chars(rand.nextInt(chars.length))).mkString }
Scalaのfor文はなかなか強力。こうやって「再代入可能な変数を減らしていく」わけですな。
選択される文字一覧には範囲型の結合を使ってみたが、これはまあおまけ。
ついでにClojureでも書いてみたらこんな感じか。
(defn generateBoundary [] (let [chars "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"] [rnd (new java.util.Random)] (str "-------" (apply str (for [i (range 40)] (nth ccc (. rnd nextInt (count ccc))))))))
ふむ、関数型っぽく書いたScalaと同じ骨組みがどこか透けて見えるじゃないですか。