3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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 リファレンスマニュアル)

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?