まずは復習
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
オブジェクトになります。
・・・ということで、ちょっとしたジョークでした。