0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Ruby のクラスは定数,じゃない

Ruby の初心者向け記事にときどき,クラスが定数であるかのような記述が見られます。
これは,

class Hoge
end

p defined? Hoge # => "constant"

というところから来ているのでしょうね。
defined? のあとに定数名を書くと "constant" という文字列を返す仕様ですが,そのとおりになっているので,Hoge が定数であることが分かります。

でね,上の例で

  • Hoge はクラスである
  • Hoge は定数である

はまあ正しいんだけれども,

  • クラスは定数である

と言っちゃうとおかしなことになります。
だって,クラスは一つのオブジェクトだし,定数はオブジェクトを指すものでしょ。

では正確にはどういうことなのか?
こうです。

class Hoge
end

というクラス定義式を実行すると,「Hoge」という名前のクラスが定義され,それが同名の定数に代入された状態になる,ということなんです。

だから Hoge はクラス名であり,それを指す定数の名でもあるわけです。
決してクラス自体が定数というわけではありません。

class Hoge
end

# クラスの名前を表示
p Hoge.name # => "Hoge"

# クラスを定義したことで同名の定数が Object に定義されたことを確認
p Object.constants.include?(:Hoge) # => true

では無名のクラスを定義するとどうなるのでしょうか。
Class.new で名前の無いクラスが作れます。

c = Class.new

# (1) 名前を持たないことを確認
p c.name # => nil

# (2) なんかの定数に代入
Hoge = c

# (3) 名前が出来た!
p c.name # => "Hoge"

# (4) 別の定数にも代入
Fuga = c

# (5) 名前は変わらない
p c.name # => "Hoge"

名前を持たないクラスの名前を求めると((3) のところ),自身が代入されている定数を探し,見つかればその定数名を自身の名前とします。
名前が出来るのは (2) の時点ではなく (3) の時点です。

(4) で別の定数に代入していますが,既にクラスは名前を持っているので,(5) では (4) の影響を受けていません。

なお,初めて名前を求めたときに複数の定数に代入されている場合,いずれの定数の名前がクラス名に採られるかは不定だそうです。
参考:Class.new (Ruby 3.0.0 リファレンスマニュアル)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?