0
0

More than 3 years have passed since last update.

[Ruby]特異メソッドの定義方法には2種類ある!

Last updated at Posted at 2021-05-16

はじめに

まずは、特異クラスや特異メソッドとは何か分かるでしょうか??
タイトルにある通り、特異メソッドの定義方法には2種類あり、特異クラス定義式による方法特異メソッド定義式による方法があります。
名前はなんとなく分かるけど、使い方が分からないとか、その逆もあることかと思います。
習得すれば、強力な武器になると思うので、ぜひ覚えていってください!

特異メソッドとは

特異メソッドとは1つのインスタンス固有のメソッドのことを指します。
特定のインスタンスに特別な性質を持たせたい場面に活躍します。

特異メソッドの定義方法

# helloオブジェクトを作成
hello = 'hello'

# helloオブジェクトにsayメソッドを作成(特異メソッド)
def hello.say(count = 1)
  count.times { print self } # ここでのselfは「hello」となる
end

hello.say(2) #=> hellohello

Object#define_singleton_methodメソッドを使用して、特異メソッド作成することも可能です。

class Foo
  class << self
    def class_name
      to_s
    end
  end
end

# helloという特異メソッドを定義
Foo.define_singleton_method(:hello) do
  "Hello! #{class_name}"
end

# helloメソッドを呼び出し
Foo.hello #=> "Hello! Foo"

特異クラスとは

あるオブジェクトに特異メソッドを定義した際に、そのメソッドが定義されるクラスが特異クラスです。
通常のクラスとは違い、特異クラスはあるオブジェクトだけが使用するクラスです。(主にselfオブジェクトであることが多いです)
そのため、特異クラスからオブジェクトを作成したり、サブクラスを作成することは禁止されています。

特異クラスの定義方法

# helloオブジェクトを作成
hello = 'hello'

# この中で定義されたメソッドはすべて「hello.メソッド名」の特異メソッドとなる
class << hello
  def say(count = 1)
    count.times { print self } # ここでのselfは「hello」となる
  end
end

hello.say(2) #=> hello, world

class << selfの解説

class 〜 endの間に定義することで、インスタンスがアクセス可能なインスタンスメソッドが定義されますが、class << self 〜 endの間に書くことで、クラス自体にメソッドが定義されます。

class Foo
  def hello
    puts 'hello'
  end

  class << self
    def sample
      puts 'sample'
    end
  end
end

# Fooクラスのインスタンスを作成
foo = Foo.new

# fooインスタンスにはhelloが定義されているので実行される
foo.hello #=> hello

# fooインスタンスではsampleメソッドにアクセス出来ない
foo.sample #=> NoMethodError

# Fooクラスのクラスメソッドなので正しく実行される
Foo.sample #=> "sample"

# Fooクラスのインスタンスメソッドなので、クラスではアクセス出来ない
Foo.hello #=> NoMethodError

終わりに

特異クラスや特異メソッドについての理解が深まりましたでしょうか?
理想は使いこなすことですが、足掛かりになればと思います。
共に頑張って習得しましょう!!

0
0
2

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
0
0