クラスはクラスクラスのインスタンスである

タイトルで出落ち感がありますが…。

naruby で時間があまった時のために用意してあったのですが、時間が余らなかったので発表しなかった小ネタです。ここで公開して供養します。


Rubyはほぼすべてがオブジェクトです。

クラスもオブジェクトです。オブジェクトということはクラスがあります。オブジェクトのクラスはオブジェクトの class メソッドで調べられます。

class Hoge
end

Hoge.class  #=> Class

Hoge クラスのクラスは Class であることがわかりました。

つまり「クラスはClassクラスのインスタンス」ということです。

クラスがClassクラスのインスタンスということは、Class.new すればクラスが作成されるわけです。

a = Class.new  #=> #<Class:0x00560d27bf2108>
Hoge = a       #=> Hoge
a              #=> Hoge

Class.new で作成したクラスには名前がついていません。定数に代入することでその定数の名前がクラスの名前となります。

つまり、

class Hoge
end

Hoge = Class.new

は同じことです。

クラス名は定数なのです。

ところで Ruby は動的に定数を削除することもできますね。クラスも削除することができます。

# Hoge クラスを定義して
class Hoge
end
# オブジェクト生成
a = Hoge.new
# 定数 Hoge を削除すると
Object.instance_eval{remove_const :Hoge}
# Hoge の参照はエラーになるけど
Hoge             #=> uninitialized constant Hoge
# でも a のクラスは Hoge のまま
a.class          #=> Hoge
# もう一度 Hoge クラスを定義
class Hoge
end
# a のクラスは Hoge だけど Hoge とは異なる
a.class          #=> Hoge
a.class == Hoge  #=> false
a.is_a? Hoge     #=> false

カオス