概要
以下のような普通のクラスを用意します。
class Hello{
String name
Integer age
String message
def createMessage(String name, Integer age) {
this.message = """Hello! I am ${name}(${age})"""
}
def setAge(Integer age) {
this.age = age + 100
}
}
特になんの変哲もないクラス。
少しJavaと違うのが、メンバ変数のセッタが宣言されている場合、Groovyの場合、直接プロパティにアクセスしようとすると、自動的にその変数用のセッタが呼ばれるということぐらいでしょうか?
例えばhelloObject.age = 100
を実行すると、プロパティのアクセスではなく、setAgeが実行されます。
このオブジェクトを操作しようとすると、以下のような形になります。
def helloObject = new Hello()
helloObject.name = "koji"
helloObject.age = 29
helloObject.createMessage("koji", 29)
assert helloObject.name == "koji"
assert helloObject.age == 129
assert helloObject.message == 'Hello! I am koji(29)'
すごく普通です。
でもhelloObjectって毎回書くのって面倒くさくない?タイプミスとかあるとイライラするし。。。
ということで、with句の出番です。
with句を使って簡略化
def helloObject = new Hello()
helloObject.with {
def hoge = 29
name = "koji"
age = hoge
createMessage("koji", 29)
//メソッドは以下の呼び方でも当然OK
//createMessage "koji", 29
}
assert helloObject.name == "koji"
assert helloObject.age == 129
assert helloObject.message == 'Hello! I am koji(29)'
//with句内で宣言したローカル変数は外部で当然参照できない!素敵!
try {
println hoge
} catch (groovy.lang.MissingPropertyException e){
println e.toString()
}
オブジェクトに備わっているwith
というメソッドに、そのオブジェクトに対して行いたい操作をクロージャとして渡してあげるだけです。
そのため、自身の変数名(helloObject)をわざわざ書かなくても良くなります。
メリット
当然オブジェクトの格納された変数名をwith句の中では書かなくていいのでソースがスッキリします。
また、オブジェクトに渡したい値などを計算したりする際に利用する一時変数がwith句外では参照できないのでwith句の外の世界を汚しません。今回の例だとhoge変数
がそうですね。(個人的にはコレがすごくありがたい!)
デメリット
思いつきません。。。
強いて言うならインデントがあるくらい?