オープンクラス
Rubyなどでは、クラスの定義をどこからでも変更することができるようになっています。これを「オープンクラス」と言います。Groovyでは、オープンクラスのような働きをする「Expando」という機能が用意されています。
obj = new Expando() obj.name = "taro" obj.message = "こんにちは!" obj.say = { name = it println message + name } obj.say("花子さん")
ここでは、objにExpandoインスタンスが設定されています。このインスタンスに、nameやmessageといったフィールドを追加し、say
メソッドを組み込みます。このように、Groovyでは後からフィールドやメソッドを必要に応じて追加していけるのです。非常に面白い機能です。
Groovy JDKについて
ここまで、テキストの出力を行うのに何気なく「println」を使ってきましたが、よく考えてみれば、これは本来、「System.out.println」と書かなければいけなかったはずです。なぜ、こんな簡単な書き方ができるのでしょうか。
Groovyでは、Javaの標準クラスライブラリに含まれているクラスの多くを標準で利用可能にしています。これのおかげで、多くのクラスをimportなしに利用することができます。また、Groovy独自に追加されているクラスなども多数用意されています。これらは「Groovy JDK」と呼ばれており、Java SEのかなりのクラスがそのまま持ち込まれています。これらのクラスを利用すれば、Javaで使っていた多くの機能を、さらに簡単に利用することが可能になります。
java.ioによるファイルアクセス
Groovy JDK利用の一例として、ファイルアクセスを行う簡単なスクリプトをあげましょう。テキストファイルからテキストを読み込む処理をGroovyで作ると、こうなります。
fpath = "C:\\Users\\tuyano\\sample.txt" file = new File(fpath) line = 0 file.eachLine { println (++line + ": " + it) }
これは、C:\Users\tuyano\sample.txtというテキストファイルを開き、中のテキストを1行ずつ行番号をつけて出力するサンプルです(ファイルのパスは適宜変更して試してください)。ここではnew Fileでファイルを作成し、それからeachLineというメソッドを呼び出して、そこにクロージャを使って読み込んだテキストを出力させています。このFileは、java.ioにあるFileですが、Java SEのクラスライブラリではなくGroovy JDKの中にあるクラスなのです。ここで使っているeachLineなどは、JavaのFileでは見られない機能です。このように、Groovyらしさを活かした機能をいろいろと追加したクラスがGroovy JDKには用意されているのです。
File
クラスを利用した別の例として、今度は指定したディレクトリの中にあるファイル類を一覧表示するサンプルを考えてみましょう。
fpath = "C:\\Users\\tuyano" file = new File(fpath) file.eachFile { println (it) }
ここでは、ディレクトリのパスを指定してnew Fileしたら、その「eachFile」を呼び出しています。これは、そのディレクトリにあるファイル1つ1つについて処理を実行するためのメソッドで、実行する処理をクロージャとしてeachFileに設定します。
クラスのimportについて
Javaではjava.io.Fileを使う際にはimportを用意しなければいけませんでしたが、Groovyではそのままクラスを使うことができますね。なぜ、クラス名だけでアクセスできたかと言えば、Groovyでは以下のクラスをすべてデフォルトでアクセスできるようになっているからです。
java.io.* java.lang.* java.math.BigDecimal java.math.BigInteger java.net.* java.util.* groovy.lang.* groovy.util.*
これ以外のパッケージにあるクラスを利用しようと思えば、Javaと同様にimportを用意する必要があります。が、Groovy JDKに標準で用意されているクラスライブラリの大半(java.mathのいくつかとjava.sql、org.w3c.domを除くすべて)がデフォルトで利用できるようになっているので、多くのケースではimportは不要でしょう。