ScalaでRubyのtimesメソッドを実現する

最近Scalaで遊んでいるんだけど、結構おもしろいです。わくわくするような機能はないのですが、なんというかいろんな機能が絶妙なバランスでミックスされている感じがいいです。お気に入りは、動的にmix-inを定義する関数なんかですね。

implicitメソッドを用いて、暗黙の型変換を利用した例を紹介します。その例としてRubyのtimesメソッドを実現してみます。Rubyのtimesメソッドは、n.timesでn回ブロックを評価するというメソッドです。まずは、irbで実験してみます。

>> 5.times{print "hello\n"}
hello
hello
hello
hello
hello
=> 5

このtimesメソッドをScalaで実現してみます。まず、timesメソッドが定義されていないことを確認してみます。

scala> 5.times{println("Hello")}
<console>:5: error: value times is not a member of Int
       5.times{println("Hello")}

たしかに、Int型にはtimesメソッドが定義されていないことがわかります。

では、IntUtilというクラスを定義して、ブロックを引数回定義するクラス timesクラスを定義します。

class IntUtil(n:Int) {
  def times(block: => Unit)= {
    for(x <- 1 to n) {
      block
    }
    n
  }
}

つぎに、型変換用関数を定義します。

implicit def int2Times(n:Int):IntUtil = {new IntUtil(n)}

できた定義を読み込ませて、実行すると、

scala> 5.times{println("hello")}
hello
hello
hello
hello
hello
res1: Int = 5

おおおお!できました。この調子で拡張すれば、他の魅力的なメソッドをもったクラスも簡単に作れそうです。