Groovyの書き方

closure

def f = {println "aaaa"}
// f instanceof Closure はtrue
f()
f.call()

def f2 = {arg-> println arg}
f2("bbb")
f2.call("bbbb")
		
def f3 = {String a,int b-> println a + b}
f3("ccc",3)
f3.call("ccc",3)

// クラスのstaticメソッドの場合
def f4 = Test01.&test02
f4()

無名関数の書き方。引数とstatementの間はHaskellみたいに->で区切る。
仮引数には型の指定を記述することもできる。

asによるキャスト

public class Test02{
  def aaa
  def bbb
  void printStr(){
    println "Test02 method"
  }
}

のようなクラスがあるとする。これをasを利用してインスタンス化する。

def obj = [aaa:"aaa",bbb:"bbb"] as Test02
// 上記を[aaa:"aaa",bbb:"bbb"] as HashMap とすると
// objはHashMapのインスタンスとなる.
if(obj instanceof Test02){
	println "test02 instance"
	obj.printStr()
        // objがHashMapのインスタンスの場合、当然printStr()は呼べない.
}
println obj["bbb"]

文字列でメソッド呼び出し

def obj = [:] as Test02
// 下記2つは同じ動作
obj.printStr()
obj."printStr"()
def arr = ["aaa","bbb"]
// アスターで配列を展開して渡すイメージ
println obj."fn01"(*arr)

メタ情報の取得

クラスのインスタンスのmetaClassフィールドからメタ情報を取得する。

new Test02().metaClass.methods.each{
  println it.name
}
new Test02().metaClass.properties.each{
  println it.name
}

また、metaClassフィールドのrespondsToやhasPropertyでメソッドの存在チェックを行うことができる。

フィールドの追加

Test02.metaClass.zzz = "zzzValue"
println new Test02().zzz

getter、setterのみ必要な場合は以下のメソッドの追加の要領で行う。

メソッドの追加

// あらかじめこの記述が必要??
ExpandoMetaClass.enableGlobally()

def old = new Test02()

def obj = new Test02()
// Test02.metaClass.bar={->"bar str"} でも同様
obj.metaClass.bar={->"bar str"}
println obj.bar()
// クラスに影響しているので新しいインスタンスでも呼べる
def obj2 = new Test02()
println obj2.bar()
// あらかじめ用意しておいたインスタンスにも影響を与えている
println old.bar()

追加のサンプル。

// metaClassにメソッドを定義する場合、文字列で指定も可能。
// また、クロージャ内ではdelegataで自身を参照することができる。
o.metaClass."hoge" = {-> delegate.bbb = "hoge"}
println "result:" + o.hoge()