Skip to end of metadata
Go to start of metadata

クロージャ


Groovyがほとんどのコンパイル言語と異なることの一つに、原始的なクラスオブジェクトとして関数を生成できることです。それによりコードの一塊が定義でき、あたかもStringかIntegerのインスタンスであるかのように取り扱うことが可能になります。


中括弧で囲まれた式「it * it」は、この式をコードとして扱うようにGroovyコンパイラに告げています。ソフトウエア用語として、これを「クロージャ」といいます。この場合、指示子"it"は、関数で与えられるいかなる値も示します。そしてこのコンパイルされた関数は上記のように変数"square"に割り当てられます。したがって今関数のように呼び出すことができます:


そしてその値として81が得られます。
このクロージャの関数のような機能は、「square」を引数のように渡すことできることに気づくまではそんなに興味深いことではありませんでした。このような引数として関数を引き渡すいくつかの組込み関数が存在しています。その例としては配列の「collect」メソッドがあります。次を実行してみましょう:


この式は、値1,2,3,4をもつ配列を生成して、上で定義したクロージャを引数として「collect」メソッドを呼び出します。このcollectメソッドは、配列における各要素を順番に引数としてクロージャ「square」をコールして、その結果を新しい配列に入れていきます。その結果は次のようになります:


引数としてクロージャを呼び出すことができる他のメソッドとしては、Groovy GDK ドキュメントを参照してください。
デフォルトでは、クロージャは「it」というひとつのパラメータを取りますが、パラメータを指定してクロージャを生成することもできます。例えば、メソッド Map.each()は、キーとそれに関するバリューをバインドする、2つの変数をもつクロージャを引数に取ります:


実行結果は:

さらなるクロージャの例


ここで、さらにいくらかのクロージャの例を見ます。最初に、2つのクロージャをみていきます。1つ目のクロージャは、そのクロージャの外にある変数に影響をあたえます。つまり、このクロージャの目的は、変数fullStringにitを追加することにより、配列orderParts内にあるスタック順の要素を一つにまとめることです。変数fullStringはクロージャの中にはありません。この2つ目の例で異っているのは、クロージャが「匿名」であるということです、つまり、与えられた名前がなく、それぞれのメソッドが呼ばれる場所で定義されます。


おそらくこの出力結果は推測できるでしょう。
次の例は、もうひとつの匿名クロージャで、今回マップに保持された値を加算していきます。

ファイル処理

 

ファイルからデータを読み込むのは比較的に簡単です。まずはmyfile.txtという名前のテキストファイルを作成します。ファイルの中身はどんな内容でもいいので、適当に文字を入力してからC:ドライブの\tempフォルダに保存して下さい。そしてgroovyConsoleで以下のコードを入力して下さい:

このコードはファイル内の各行の先頭に"File line: "をつけて出力します。コードの最初の二行はファイルの場所を示す変数を宣言するだけです。変数の名前は特に意味ありません。これらの変数を使う時も、単に内容を結合するだけです。ここで注意すべきのは、Groovyではバックスラッシュ記号に特殊な意味合いがあるので、"本当のバックスラッシュ記号"を表現したい場合、二回書く必要があります。

次の"myFile ="で始まる行は、新しいFileオブジェクトを作成します。オブジェクトというのは関連性を持つメソッドとデータの集合です。たとえば、ファイルオブジェクトは場所を示すデータ(この例でいうと"C:\temp\myfile.txt")を持っていて、存在しているファイルを削除するためメソッドも持っているかもしれません。この例で使用するメソッドは、最後の行で呼び出したeachLineメソッドだけです。その前の行はクロージャの定義で、ここまで来て何回も見たはずです。

文字列処理

Groovyの文字列はJavaの文字列のすべての機能を備えています。実際、Groovyの文字列はJavaの文字列に少しおまけをつけただけの物です。なので、JavaのStringクラスのドキュメントを参考にして、どんなことできるかを調べることもできます。例として、"Method Summary"の章節の"split"メソッドを見てみましょう。このメソッドは結構有用で、正規表現を元に文字列を分割することができます。正規表現については後の文書でお話するけど、最も簡単な正規表現は一つの文字(キャラクタ)だということを、先に覚えるべきです。たとえば"2005-07-04"という日付の次の7月4日を取得したい場合、この日付の構成を分割して年に1を足せばよいのです:

このコードは前説明したいくつかの内容をまとめました。新しいことは二点だけで、うちの一つはStringのsplitメソッドの使用です。そしてもう一つはStringを元にしたtoInteger()の呼出です。このtoIntegerの呼出は、データをStringではなく数字として扱いたいという意図をGroovyに知らせるためです。三行目最後の".toInteger()"なしで実行してみて、何が起きるかを観察して下さい。

あともう一つのことも気づいているかもしれませんが、toIntegerはJavaのドキュメントに含まれていません。これはtoIntegerがGroovyでStringに追加された物の一つだからです。Javaオブジェクトに対するGroovy拡張に関するドキュメントも読んでみるといいでしょう。

  • No labels