まずは復習
Ruby を使っていれば、範囲オブジェクトを必ず一度は目にすると思います。
範囲オブジェクト (もしくは Range オブジェクト) を生成する演算子には .. と ... の 2 種類があり、.. は終端を含みますが ... は終端を含まないという違いがあります。実際に for 式で調べてみれば明白ですね。
i = 3
for k in 0..i # 0 から 3 までが出力される
p k
end
for k in 0...i # 0 から 2 までが出力される
p k
end
さて・・・
上の例では、0..i と 0...i という 2 つの範囲オブジェクトを使っていますが、実はこの 0 を $ という特殊な記号に置き換えてもオブジェクトが作れます。ご存知でしたか?
知らなかったという方は、下のコードの実行結果がどうなるか予想してみてください。
i = 3
p $..i
p $...i
解答は下の方にあります。
解答
(0+0i)
0..3
真面目に考えた方、ごめんなさい・・・。
解説
まず、Ruby では $ だけが意味をなすことはありません! 上の文章を読むと $ が単独で何か意味があるように感じるかもしれませんが、これは意図的なミスリーディングです。
Ruby には $. という特別な変数が用意されていて、これは何らかの IO オブジェクトが最後に読み込んだ行の行番号を返します。何も読み込んでいない場合は 0 を返すことになっているので、$..i は 0.i と等価です。これは、0 という Integer オブジェクトに対し i という名前のメソッドを呼んでいると解釈されます。このメソッドは、実部が 0 で虚部がレシーバ自身となるような Complex オブジェクトを返すので、0.i の評価結果は 0+0i となるわけです。
一方、$...i は上で述べたのと同様に 0..i と等価です。今、変数 i の値は 3 なので、これは 0..3 という Range オブジェクトになります。
・・・ということで、ちょっとしたジョークでした。