ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

Rubyの定数ってうわー


かなり古い資料なのですが、これを見ているとRubyの定数がアレだということがわかりました。

定数なのに上書きできる(ただしわけあり)

上のページにはこうあります。

変数名が大文字で始まるのが定数である。定数と言うからには(最初の)一回 しか代入できないものだ。

Const = "content"
PI = 3.1415926535

p(Const)   # "content"と表示される

二回代入するとエラーになる。と言いたいのだが、実は警告だけでエラーにならない。

Ω ΩΩΩΩ ナ、ナンダッテー
え、それって定数じゃないのでは…でも、これにはやむにやまれぬ理由があったようです。このあと続けてこうあります。

これは、Rubyプログラム自体を操作するアプリケーション、例えば 開発環境などで、同じファイルを二回ロードしたときにエラーにならないようにするためだ。つまり実用のためにやむを得ず認めているだけで、本当はエラーにしたいのである。実際にもバージョン1.1まではエラーになっていた。

C = 1
C = 2   # 現実には警告が出るだけだが、理念としてはエラー

ということだそうです。だからって頻繁に定数を書き換えるようなプログラムは書かないようにしましょう。で、これで終わりとといいたいところですが、まだ更に続く衝撃の展開が。

さて、定数という言葉で騙される人が多いのだが、定数というのは「いったん指すオブジェクトを記憶したら二度と変えない」という意味である。定数の指すオブジェクトそれ自体が変わらないわけではない。

やっぱり書き換えられるじゃないですかーやだー
もちろん破壊的メソッドを呼びださなければいいだけの話ですし、変更禁止を強制したければfreezeというメソッドを使えばいいのです。

クラスも定数だった

はいそうなんです。

class Hoge
  #some methods, constants, variables...
end

上のプログラム、実は事実上クラスを表すオブジェクトのクラスであるClassクラスのHogeという定数を定義する文だったんです。
な、何を言っているのかわからないと思うが(ry
つまり、

Rubyにおいてクラス名とは定数名と同義である。

ということなのです。この一文、かなり衝撃的な事実ですね。ということは、「Hoge.new」というのはHogeという定数に特有のnewというメソッドを呼び出していた、ということになります。*1ということなので、

そんなわけでRubyではnewは予約語ではない。

そう、newはClassクラス特有のメソッドなのでした。

Rubyの世界では、頭文字が大文字なら定数なんだよ!

これが真理です。よってモジュールも例外なく定数です。書き換えることができようがRubyの小人さんたちが定数だといえばそれは定数なのです。

*1:このように、ある値に特有のメソッドのことを「特異メソッド(Singular Method)」という