GStringは遅延評価か?

GStringが遅延評価かどうかが話題になっているようです:
http://genzou-postit.blogspot.com/2009/06/gstring.html

「Groovyイン・アクション」をお持ちの方はp.409の13.2.5を読んでみてください。以下、自分の理解をまとめてみます:

  1. GString内のプレースホルダ(${〜}の部分)の中の式はただちに評価される
  2. GStringオブジェクトは、この評価結果(式の値)として返されたオブジェクトへの参照をそのまま保持しておく
  3. GStringオブジェクト自体が文字列化されるタイミングで、保持している各プレースホルダの評価結果オブジェクトも文字列化される

つまり、

  • プレースホルダ内の式の評価はeagerに行われる
  • 式の値の文字列化はlazyに行われる

ということです(ちょっとややこしいけど)。

というわけで、式の値が文字列や数値などimmutableな場合は遅延評価には見えませんが、リストやStringBufferなどの変更可能なオブジェクトの場合は、GString構築後にそのオブジェクトを変更すると、GStringの文字列化結果にも反映される(遅延評価に見える)ことになります。

例1:式の値がimmutableなオブジェクトの場合

i=1
gs="$i"           // gsにはiが指す1という数値オブジェクトへの参照が保持される
++i               // iをいじっても数値オブジェクト1自体が変更されるわけではない
assert gs == "1"  // iの操作はgsの文字列表現には影響しない

例2:式の値が変更可能なオブジェクトの場合

l=[1]
gs="$l"                // gsにはlが指す[1]というリストオブジェクトへの参照が保持される
l<<2                   // l経由でリストオブジェクト自体が変更される
assert gs == "[1, 2]"  // lの操作がgsの文字列表現に反映された

以上、なんか間違ってたらご指摘ください。