【Ruby】特異メソッドと特異クラスを理解する

2025-10-21 00:00

前回の記事で include / prepend / extend について解説したが、その中で「特異メソッド」「特異クラス」というワードが出てきた。

【Ruby】include / prepend / extend の違いを理解する | tatsuya-develop Engineer Blog
先輩エンジニアから紹介してもらった「メタプログラミングRuby 第2版」を読んでいる途中だが、学びがあるのでこまめに投稿してみようと思う。 メタプログラミングRuby 第2版 本書はRubyを使ったメタプログラミングについて解説する書籍です。メタプログラミングとは、プログラミングコードを記述するコードを記述することを意味します。前半では、メタプログラミングの背景にある基本的な考えを紹介しながら、動的ディスパッチ、ゴーストメソッド、フラットスコープといったさまざまな「魔術」を紹介します。後半では、ケーススタディとしてRailsを使ったメタプログラミングの実例を紹介します。
【Ruby】include / prepend / extend の違いを理解する | tatsuya-develop Engineer Blog favicon blog.tatsuya-develop.com
【Ruby】include / prepend / extend の違いを理解する | tatsuya-develop Engineer Blog

聞き馴染みのないワードだったのと、rubyをやるにおいて重要そうな概念だったので、これを機に理解を深めてみる。

特異メソッドとは

特定のオブジェクト「だけ」に追加されるメソッドのこと。

通常のインスタンスメソッドは、そのクラスから作られた全てのインスタンスで利用できる。

一方、特異メソッドは特定のオブジェクト専用のメソッドとなる。

実際に動かしてみる

事前準備

module Greeting
  def say_hello
    "Hello from #{self}"
  end
end

class Member
  # Memberクラスの特異クラスにGreetingのメソッドを特異メソッドとして追加
  extend Greeting
end

class Admin
end

member = Member.new
admin = Admin.new
# adminインスタンスの特異クラスに特異メソッドを追加
admin.extend(Greeting)

クラスでの特異メソッド

# Member は say_hello を持つが Admin は say_hello を持たない。
Member.say_hello
# => "Hello from Member"

Admin.say_hello
# undefined method 'say_hello' for class Admin (NoMethodError)

# Member の特異メソッド
Member.singleton_methods
# => [:say_hello]

# Admin の特異メソッド
Admin.singleton_methods
# => []

インスタンスでの特異メソッド

member = Member.new
admin = Admin.new

# adminインスタンスの特異クラスに特異メソッドを追加
admin.extend(Greeting)

# admin は say_hello を持つが member は say_hello を持たない。
member.say_hello
# undefined method 'say_hello' for an instance of Member (NoMethodError)

admin.say_hello
# => "Hello from #<Admin:0x0000000127997870>"

# member の特異メソッド
member.singleton_methods
# => []

# admin の特異メソッド
admin.singleton_methods
# => [:say_hello]

補足

💡 重要: クラスの特異メソッド = クラスメソッド

特異クラスとは

そのオブジェクト専用のメソッドを保存する隠れたクラスのこと。

全てのオブジェクトが潜在的に特異クラスを持っている。

実際に動かしてみる

※「特異メソッドとは」のときに使用した事前準備を使う。

クラスの特異クラス

# Member の特異クラス
Member.singleton_class
# => #<Class:Member>

# Admin の特異クラス
Admin.singleton_class
# => #<Class:Admin>

インスタンスの特異クラス

# member の特異クラス
member.singleton_class
# => #<Class:#<Member:0x00000001256d8500>>

# admin の特異クラス
admin.singleton_class
# => #<Class:#<Admin:0x00000001256d8460>>

図にしてみた

ruby_singleton_class_structure

ポイント1: 特異メソッドは特異クラスに保存

  • インスタンスA・Bの特異クラスに「特異メソッド」が保存される
  • クラスの特異クラスにも「特異メソッド」が保存される(= クラスメソッド)

ポイント2: 独立性

  • インスタンスAとBは別々の特異クラスを持つ
  • 一方の特異メソッドは他方に影響しない

補足

特にこの記事内では言及していないが、図の中では表現したので一点補足。

インスタンスはメソッドを直接持たない

  • インスタンスA・Bは「メソッド」部分を持たない
  • インスタンスは、クラスのメソッドを参照する仕組み

この記事をシェアする

© 2025 tatsuya-develop