わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

nilガードをthe final draft Ruby Specificationで調査

きっかけは,Webではなくメールでした.「[ruby-dev:42280] Ruby言語仕様書最終原案」と題するメールが届きました.本文は,ぐぐっても出ますが,http://blade.nagaokaut.ac.jp/ruby/ruby-dev/index.shtmlから番号を指定するのが,今後も使えて便利かと思います.
さっそく,http://www.ipa.go.jp/software/open/ossc/english/ruby/ruby_draft_specification.htmlにアクセスし,1.8.7に基づいていること,draft specificationを再配布するのはいいけどその修正版の再配布をしてはいけないあたりを読み取りながら,ダウンロードしました.Ruby_final_draft_enu_20100825.pdf というファイル名です.
漫然と読んでも,自分のためにならないので,先日のnilガードに集中して,読んでみました.

  • 6.6 Boolean values (p.17)
  • 8.7.5 Operators (pp.24-25)
  • 11.2 Logical expressions (pp.46-49)
  • 11.4.2.3 Abbreviated assignments (pp.71-73)

そこから知ったことを書いておくと,

  • true/falseと別に,真/偽となる値を表す表現があって,trueish/falseish objectという.
  • 自己代入*1において,&&=,||=は特別扱いされていない模様.例えば,11.4.2.3.2を読む限りでは,「a ||= 5」は「a = a || 5」であって,「a || (a = 5)」と解釈できない.

さて,http://d.hatena.ne.jp/takehikom/20100913/1284318992を書いたときに,一つ気になることがありました(なので翻訳者様からのコメントも,放置していました).それは,『「a ||= []」は「a = a || []」ではなく,「a || (a = [])」』と言うための,英文かつ仕様としての根拠です.日本語については,上記エントリでリンクしています.英文では,新たに知ったfalseishで検索をかけたところ,

というのを見つけまして,2009年3月,またそのリンクによると2008年3月の段階で,『「a ||= []」は「a = a || []」ではなく,「a || (a = [])」』はすでに知られていたルールだったようです.しかしいずれも「こうなんだよ」であり,仕様としての根拠は,見当たりません*2
今回のfinal draftを根拠にできず,nilガードを巡る一人旅はまだまだ続くことになります.

*1:自己代入 = abbreviated assignmentではなさそうで,abbreviated assignmentには,「OP=」演算子(Cの授業で言っている複合代入演算子)による代入演算と,[]が絡む代入演算,メソッド呼び出しが絡む代入演算がある,という解釈でいいのかな….

*2:http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case/#comment-88の"the fact that in simple assignments x = x || y is the same as x || x = y"にはぎょっとして,sample.rbにコードを追加して確認しましたが,「x = x || y」と「x || x = y」は等価ではありませんでした.