2
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のメタクラスってなんだ?

Last updated at Posted at 2020-08-21

はじめに

Rubyのメタクラスについて本質的な解説をしている人がいなかったので自分なりに解説してみました。

※前提として特異メソッド/特異クラスを多少知っている人向けです

Classクラスについて

Rubyにおいて”クラス”はClassクラスのインスタンスであるというのは、ある程度Rubyをかじったことがある人ならば聞いたことがあると思われる。
その通り、RubyにはClassクラスがあり、それをインスタンス化してクラスを定義することが可能である。
以下の2つは同義である。


class Hoge; end
Hoge = Class.new

メタクラスとは

一方で、Classクラスの特異メソッドnewについてリファレンスを読んでみると以下のような記述がある。

新しく名前の付いていない superclass のサブクラスを生成します。
名前のないクラスは、最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。

「名前の付いていない superclass のサブクラスを生成します」
そう、Class.newによって生成されるオブジェクト自体は無名のクラスなのである。


a = Class.new
p a.name #=> nil

実はこれがメタクラスに該当する。
メタクラスは名前を持たないため、クラスでありながら定数ではなく変数に保持される。
また、メタクラスは定数に代入すると、定数名をクラス名としてメタクラスを参照することが可能である。


a = Class.new
Hoge = a
p a.name #=> "Hoge"
p Hoge.name #=> "Hoge"

つまりHogeクラスはClassクラスから直接生成されるオブジェクトではなく、あくまでメタクラスを参照しているだけである。

メタクラスとクラスメソッド

メタクラスに特異メソッドを定義すると、Hogeクラスの静的メソッドのように振る舞わせることができる。


a = Class.new
Hoge = a

def a.hello
   puts "hello"
end

a.hello #=> "hello"
Hoge.hello #=> "hello"
hoge = Hoge.new
hoge.hello #=> NoMethodError

ちなみにこれがRubyのクラスメソッドと呼ばれる物の正体である。
クラスメソッドの定義方法として使われる特異クラスを開く方法は、つまるところメタクラスにメソッドを追加しているわけである。


class Hoge
   class << self #Hogeクラス自身の特異クラスを開く
      def hello
         puts "hello"
      end
   end
end

Hoge.hello #=> "hello"

最後に

メタクラスはユーザーに意識させたくないクラスらしく、ぶっちゃけリファレンスによるとたいして重要なことでもないみたいです。
ただ、メタクラスがよくわからずモヤモヤしている人や本質的な部分の理解を深めたい人の一助となっていただければ幸いです。

2
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
2
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?