スキップしてメイン コンテンツに移動

特異クラスでRubyメタクラス

特異クラスでRubyメタクラス

特異クラスとメタクラスの基礎

Rubyにおける特異クラス(eigenclass)は、オブジェクト固有の振る舞いを定義するための仕組みです。実際には「メタクラス」と呼ばれる内部クラスで、オブジェクトのクラスに対して一時的に追加されます。特異クラスは、クラスメソッドの実体を保持する場所でもあり、オブジェクト固有のメソッドを定義する際に不可欠です。

メタクラスは階層構造を持ち、ObjectクラスのメタクラスがObjectクラスの親となるように、継承チェーンが形成されます。これにより、特異クラスを通じてクラスメソッドの継承やオーバーライドが可能になります。

eigenclassの実装と使い方

特異クラスは以下のように取得できます。

class_obj = Object.new
eigen = class_obj.singleton_class
eigen.class # => Class

このeigenclassにメソッドを追加すると、対象オブジェクトにのみ適用されます。

class_obj.singleton_class.class_eval do
  def greet
    "Hello from #{self}"
  end
end
class_obj.greet # => "Hello from #<Object:0x00007f...>"

特異クラスはメタクラスの一種であり、クラスメソッドの実体を保持する場所としても機能します。クラスメソッドを定義する際は、クラスオブジェクトの特異クラスに直接メソッドを追加します。

クラスメソッドの実体と特異メソッド

クラスメソッドは実際には特異メソッドです。クラスオブジェクト自体がオブジェクトであるため、クラスメソッドはそのオブジェクトの特異クラスに定義されます。

class Person
  def self.species
    "Homo sapiens"
  end
end
Person.species # => "Homo sapiens"

上記のself.speciesは、Personクラスの特異クラスに定義されたメソッドです。特異クラスを直接操作することで、クラスメソッドを動的に追加・変更することも可能です。

オブジェクト固有の振る舞いを制御する

オブジェクト固有の振る舞いを制御するには、特異クラスにメソッドを追加するだけでなく、メタクラスの継承チェーンを利用します。例えば、あるオブジェクトにだけ別の振る舞いを持たせたい場合、以下のようにします。

class A; end
a = A.new
b = A.new

a.singleton_class.class_eval do
  def speak
    "a speaks"
  end
end

b.singleton_class.class_eval do
  def speak
    "b speaks"
  end
end

a.speak # => "a speaks"
b.speak # => "b speaks"

このように、特異クラスを使うことで、同じクラスのインスタンスでも異なる振る舞いを持たせることができます。

階層構造とメタクラスの関係

RubyのオブジェクトはすべてObjectクラスのインスタンスであり、Objectクラス自体もClassクラスのインスタンスです。メタクラスはこの階層構造の中で、クラスオブジェクトの振る舞いを定義する役割を担います。

メタクラスの階層は以下のように構成されます。

  • Object#singleton_class → Class#singleton_class → Module#singleton_class → ...

このチェーンを辿ることで、クラスメソッドの継承やオーバーライドが可能になります。特異クラスとメタクラスの関係を理解することで、Rubyの高度なメタプログラミングを自在に操ることができます。

この記事はAIによって作成されました。

コメント