until修飾子と変数定義の関係
ary = [ "aaa{{bbb}}ccc" * 5] ary += str.partition(/\{\{.+?\}\}/) until (str = ary.pop).empty? p aryみたいに書いたら
est.rb:11:in `
': undefined local variable or method `str' for main:Object (NameError) て怒られた。
http://d.hatena.ne.jp/dicdak/20090303
おとなり日記に気になるエントリがあったので,試してみたら,確かにエラーが出る出る.1.9.1だけじゃなくて,1.8系列でも同じエラーが出てくれる.エラー内容からすると,untilの右辺式で代入しているにもかかわらず,左辺式のstr変数参照で,変数が未定義だと怒っているわけか.
ary = [ "aaa{{bbb}}ccc" * 5] str = "" ary += str.partition(/\{\{.+?\}\}/) until (str = ary.pop).empty? p ary
と,予め定義してやると,ちゃんと通るみたいだった.
つまり,until修飾子が付く文脈であっても,評価順序とはお構いなしに左から右に制約検査していくので,その結果,左辺式が引っかかってるってことかしら・・・?
真偽を確かめるべくグーグル先生に聞いてみたりすると,なんとFAQレベルのお話だった.
2.3 ローカル変数はいつ参照可能になるのでしょうか
Rubyスクリプトは,Rubyインタプリタに実行させようとすると,まず最後まで一度読みこまれ,構文解析されます.構文上問題が生じなければ,構文解析で作られた構文木が最初から実行に移されます.ローカル変数が参照可能になるのは,この構文解析の時にローカル変数への代入文が見つかった時です.
http://www.swlab.it.okayama-u.ac.jp/man/ruby/rubyfaq-jp-990825/rubyfaq-jp-2.html
(中略)
ローカル変数のこのような振舞いに悩まされないためには,ローカル変数が参照される文より前に,a = nil といった代入文を置くことがすすめられています.こうすると,ローカル変数の参照が速くなるというおまけもついています.
バッドノウハウ的な何かを感じるけど,まあしかたないかぁ・・・