GroovyにはJava Development Kit(JDK)を拡張するGroovy Development Kit(GDK)があります。GDKのおかげで、私達はJDKクラスと一緒に多くの便利なメソッドを使えます。ではそれらのメソッドはどこに定義されているのでしょうか? どうやってJDKのクラスに追加しているのでしょうか?
1つ目の疑問の答えは"org.codehaus.groovy.runtimeパッケージ下のクラス内"です。 そのクラスのうちいくつかを紹介します。
- DefaultGroovyMethods: 汎用メソッドを定義します。但しいくつか非汎用メソッドも定義します。初期のバージョンでは、ほとんどのGDKメソッドがここに定義されており、Groovyチームはまだこれらの移動を完全には終わらせていません。
- DateGroovyMethods: 日付/時間関連メソッドを定義します。
- ProcessGroovyMethods: プロセス管理関連メソッドを定義します。
- SwingGroovyMethods: Swing関連メソッドを定義します。
これらのメソッドには全てpublic static修飾子がついています。例えば、DefaultGroovyMethodsはdump()メソッドを次のように定義しています(dump()メソッドは過去のポスト、"Groovyによる汎用toString()"で紹介しました):
----
public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
...
public static String dump(Object self) {
...
}
...
}
----
2つ目の疑問の答えは少し複雑です。なぜなら正確には追加されているわけではないからです。ではどのように呼び出されているのでしょうか? 例を出して説明します。次のようにjava.net.URLクラスのオブジェクトに対しdump()メソッドを呼ぶとします:
----
def url = new URL('http://groovy.codehaus.org/')
url.dump()
----
この場合、Groovyは次の2つのステップでdump()メソッドを呼びます:
1. DefaultGroovyMethods.dump()のメタデータ(groovy.lang.MetaMethod)を持つorg.codehaus.groovy.runtime.callsite.MetaMethodSiteクラスのオブジェクトを生成します。
2. そのMetaMethodSiteオブジェクトを経由し、MetaMethodオブジェクトのinvoke()メソッドをURLオブジェクト引数とともに呼び出します。
つまり、簡単に言うとGroovyはバイトコードの生成時にurl.dump()をDefaultGroovyMethod.dump(url)に置き換えるわけです。
このMetaMethodSiteクラスはGroovyランタイム専用のクラスなので直接使うことはできません。でもがっかりしないでください。Categoriesを使えば同じことができます:
----
class MyMethods {
public static String myDump(Object self) {
...
}
}
use (MyMethods) {
def url = new URL('http://groovy.codehaus.org/')
url.myDump()
}
----
No comments:
Post a Comment