Writableは何のため?
Groovyにはgroovy.lang.Writableというインターフェースがあります。定義は以下の感じ。
package groovy.lang; interface Writable { Writer writeTo(Writer out); }
また、クロージャにはasWritable()というメソッドがあり、「クロージャ引数である出力ストリームoutに対して出力処理を行うクロージャ」を、Writableインターフェースを実装したクラスのインスタンスに変換します。つまり、
x = { out -> /* outに対する出力処理 */ }.asWritable()
は、
class Hoge implements Writable { Writer writeTo(Writer out) { /* outに対する出力処理 */ } } x = new Hoge()
とだいたい等価です。
なおこれは、例の「クロージャをインターフェースに変換する方法」を使えば、
x = { out -> /* outに対する出力処理 */ } as Writable
と同じでもあります(試してませんが)。
んで、本題ですが、Writableとは何か、ですが、これはおそらく、ストリーミング的に処理をするための道具です。たとえば、テンプレートエンジン*1を展開するときに
HogeTemplate t = new HogeTemplate(..) String result = t.expand(binding) println result
とやると、展開結果後のテキストの文字列領域が必要になります。この領域は使ったらすぐ解放するものであり、展開結果が巨大になると性能に対する負荷もバカになりません。
しかし、
HogeTemplate t = new HogeTemplate(..) Writable tw = t.asWritable() tw.writeTo(System.out)
のようにテンプレート展開エンジンをWritableとして実装できれば、ストリーミング処理になり、ある程度のバッファがあれば、メモリ使用量が限定されます(展開後のテキストの量に応じたメモリを使わなくても良い)。
良くできた仕組みと思います。
ただ、ストリーミング処理自体は普通にやるべきことで、Groovyの発明ではなく、世のテンプレートエンジンと呼ばれるもので実用的なもの(JSP,Velocity,ERB..)はあまねくこの種の処理をやっているでしょうね。
*1:以下は適当な例としてのテンプレートエンジンで、メソッドとかは実際のGroovyのSimpleTemplateとかと異なります。ただ、実際の処理方法としては、SimpleTemplateEngineやGStringTemplateEngineも原理的にはこんなことをやっているようです。