7
4

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 5 years have passed since last update.

Rubyの各メソッドと優先順位

Last updated at Posted at 2018-03-11

Rubyでメソッドを呼び出すことをメソッドの探索やメソッド名の解決と言いますが、Rubyはこれらをどの様に処理しているか簡単にまとめてみようと思います、初学者向け。

objというオブジェクトがあったとして、obj.mというメソッド呼び出しがあった場合、Rubyは以下の優先順位でメソッドの探索を行います。

  1. objの特異メソッド
  2. objのクラスのmというインスタンスメソッド
  3. objのクラスがインクルードしているモジュールのインスタンスメソッド(includeされた順とは逆順でモジュールを検索する)
  4. スーパークラスのインスタンスメソッド
  5. スーパークラスがインクルードしているモジュールのインスタンスメソッド
  6. 見つからない場合、method_missingメソッドが呼び出される

特異メソッドやらインスタンスメソッドなど色々出てきたのでそれぞれについて簡単に説明します。

#特異メソッド(singleton method)
特異メソッドとは、特定のオブジェクト固有のメソッドです。

obj = "object"           # Stringクラスのオブジェクト

def obj.hello            # objの特異メソッド
  puts "hello " + self
end

obj.hello                # => "hello object"

obj2 = "object2"
obj2.hello               # helloはobjの特異メソッドなのでobj2では使えません

obj2では、undefined method `hello'とエラーを吐いてしまいます。

#インスタンスメソッド
その名の通りインスタンスオブジェクト(Hoge.newしてできるやつ)から呼び出せるメソッドです。

class Greeting
  def hello              # Greetingクラスのインスタンスメソッド 
    puts "hello"
  end
end

obj = Greeting.new
obj.hello                # => "hello"

Greeting.hello           # これはGreetingクラスのクラスメソッドです、エラーを吐きます 

急に出てきたクラスメソッドというやつはクラスオブジェクトが持つメソッドで、この例で使おうとするとGreetingクラス内でdef self.helloの様に定義してGreeting.helloという様に使います、インスタンスを生成していない所に注意してください。

#インクルードされたモジュールのインスタンスメソッド
Rubyでは、include Hogeと書くことで、Hogeモジュールが他の所でも使える様になります。
モジュールとはメソッド等をまとめることができるもので、オブジェクトが作成できないクラスの様な感じです。

module Greeting
  def hello
    puts "hello"
  end
end

class NoHello
  include Greeting      # Greetingモジュールをインクルード
end

obj = NoHello.new
obj.hello               # => "hello"

この様に、helloメソッドを実装していないクラスのインスタンスからhelloメソッドを呼び出すことができます。

#スーパークラスのインスタンスメソッド
Rubyでは、スーパークラスを継承してサブクラスを作成することで、スーパークラスのメソッドを呼び出すことができます。
Rubyは純粋なオブジェクト指向の言語なので、全てのクラスはObjectというスーパークラスのサブクラスです。

class Super           # スーパークラス
  def hello           # スーパークラスのインスタンスメソッド
    puts "hello"
  end
end

class Sub < Super     # Superクラスを継承してサブクラスを作成
end

obj = Sub.new
obj.hello             # => "hello"

obj2 = Super.new
obj2.hello            # もちろんこれも"hello"です 

スーパークラスがインクルードしているモジュールのインスタンスメソッドというのは、Superの中でインクルードした場合を考えればわかると思います。

#missing_method
missing_methodは、メソッドを探索してどこにも見つからなかった場合に最終的に呼び出されるメソッドです。
呼び出されるとNoMethodErrorを出します。

obj = "object"
obj.no         # => "undefined method `no' for "object":String (NoMethodError)"

ちなみにRubyは、メソッド探索に成功するとキャッシングするので同じメソッドをその後検索するときは高速に処理される様になります。

#参考文献
プログラミング言語 Ruby

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?