No Programming, No Life

プログラミング関連の話題や雑記

Groovyのwith

Server error
のコードを見ていて、withがあることに気づいた。
withのこと - Grな日々(uehajの日記)
あたりを見て使用法がやっとわかった。

使用例

既存クラスのCalendarとかだとこんな感じに使える。

def calendar = Calendar.instance  
calendar.with {  
  clear()  
  set MONTH, JULY  
  set DATE, 4  
  set YEAR, 1776  
  println time  
}  

withの中では変数calendarのフィールドやメソッドが "calendar." の指定なしに使えるわけですね。

ちょっとテスト

実現方法はクロージャでデリゲートしている模様。ステートメントじゃなくてクロージャとして機能提供するあたりがGroovyっぽくて素敵。
id:uehaj さんのところではmetaClassを使って試していたので、ここではクラス宣言で試してみます。

class WithTest {
  def field
  def method() { return field }
  void with(Closure clos) {
    clos.delegate = this
    clos.resolveStrategy = Closure.DELEGATE_FIRST 
    clos.call()
  }
}

def test = new WithTest(field:'aaa')
test.with {
  assert 'aaa' == field
  assert 'aaa' == method()
}
備考

ClosureのresolveStrategyに設定可能な値は、OWNER_FIRST、DELEGATE_FIRST、OWNER_ONLY 、DELEGATE_ONLY があるようです(in groovy.lang.Closure)。デフォルトはOWNER_FIRST。