Yokohama.groovy #2 で GString にハマった話
2012/08/20 Yokohama.groovy #2 #yokohamagroovy #twitgroovy - Togetterまとめ
第2回 Yokohama.groovy をやってきました。
今回も会場はタネマキさん。
夜なのでビール片手に、総勢 4 人で開始です。
今回の範囲は、「3.4 プロパティ/フィールド/メソッドの参照方法」と「3.5 データ型」を中心に、写経して実行結果を確認しながら読み進めました。
- 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/06
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 392回
- この商品を含むブログ (155件) を見る
話したことなど
- 省略できたり、違う書き方ができたりすることが多くて便利
- 真偽値判定は ==false じゃなくて ! を使う
- GString 難しい
- 遅延評価のところではまる
そんな感じでやっていたら、いつの間にか、@kyon_mm さんや @irof さんが Twitter で参加(?)してくれてました。
そして GString でハマる
今回の一番ハマりポイントはGStringでした。
最初は、Linux コマンドとかでもあるような、変数が展開されて文字列が取り出せるんだなと読み流していました。
ところが、リスト3.33 で (D) になる理由がよくわからずもやっとしてしまい、みんなであーでもないこーでもないと悩んでました。
特に本文中の、"GString の遅延評価的な性質を活かすためには、Imutable ではない値(配列やリストなど)を保持させ、GString のまま持ち回すようにします" という表現に惑わされてたような気がします。
"GString のまま" とか言われると、Imutable な値を展開したら GString じゃなくなるみたいに見えませんか?私だけですかね?
list=['x'] def gs = "$list ${list[0]}" //(A) assert gs instanceof GString assert gs == "[x] x" //(B) list[0]='y' //(C) assert gs == "[y] x" //(D)
ありがたいことに、@kyon_mm さんと @irof さんが色々説明してくれたおかげで理解が進みました。
@irof さんのサンプルコードがとても参考になりました。
GStringのは単に参照は変えられないって感じですかねー。参考になるかわからないですが っ URL #twitgroovy #yokohamagroovy
GStringの評価が遅延されてるように見えるケースの · GitHub
今のところ、私はこのように理解しました。
- def gs = "$list ${list[0]}" //(A)
- $list は、変数 list の参照を保持している
- list は、List 型であり mutable
- $list[0] は、list[0] に格納されている値 'x' (String型のインスタンス)の参照を保持している
- 'x' は String 型であり imutable
- $list は、変数 list の参照を保持している
- list[0]='y' //(C)
- assert gs == "[y] x" //(D)
- $list は、変数 list の参照なので、展開すると [y]
- $list[0] は、(A) の時点で、 'x' の参照となっているので展開しても x のまま
- @irof さんのサンプル 3.groovy
- 13,14 行目で $list が変わらないのは、変数 list のインスタンスが変わったため
- GString は設定された参照を変えられない
その他
集まって話しながらという形式は、一人で読んでいた時には気にならなかった点に気づくことができていいですね。
参加された方々、@kyon_mm さんと @irof さん、ありがとうございました。