Rubyの::演算子について
ruby*1では、A::B
という形式の式は、NODE_COLON2
という名前になる。::
という演算子の式なので、コロンが二つでCOLON2だろうか。とても素直な名前である。::
の両端には普通はA
とかB
とかの定数名を書くが、call
メソッドを呼ぶための構文でも使う。
irb(main):001:0> self::(3) NoMethodError: undefined method `call' for main:Object irb(main):002:0> (:succ.to_proc)::(3) => 4
これいつからある機能なんだろ……
さて、rubyのソースコードを見ていると、NODE_COLON3
という定義もある。これはコロンが三つ並んだ演算子ではなく、トップレベルの定数を参照するための演算子で、::Object
とか書くと作ることができる。なんで3にしちゃったのかあまり合理的な理由がなさそうな気がする、とても投げやりな感じの、見つけると楽しくなる名前である。*2
なんで、NODE_COLON2
を流用するのではダメかというと、
node.h:#define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0) node.h:#define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0)
となっていて、さらに
parse.y: $$ = NEW_COLON2(0, $$);
というのがあって、つまりNEW_COLON3(n)
とNEW_COLON2(0, n)
を区別するためなんだけど、なんで区別する必要があるのかはよくわからない。NODE_COLON2
を流用しようとしていろいろ試行錯誤したけどうまくいかなくて、力尽きて良い名前も思いつかずにいつのまにかNODE_COLON3
になったんだろうと想像している。
ちなみにNODE_COLON
やNODE_COLON1
は定義されていない。Rubyではコロンはシンボル:symbol
やハッシュ{ key: value }
に使われるが、それらは字句解析か構文解析の時点で、他の構文に取り込まれてしまう。