Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rubyの継承とミックスイン メソッドの見つけ方

Avatar for 170 170
March 21, 2017

Rubyの継承とミックスイン メソッドの見つけ方

Avatar for 170

170

March 21, 2017
Tweet

Other Decks in Programming

Transcript

  1. レシーバのオブジェクトが持っているメソッドを呼び出せる インスタンスメソッドの呼び出し class Test def instance_method p "instance method!" end

    end test = Test.new # クラスのインスタンス (=オブジェクト) test.instance_method # => "instance method!"
  2. class Test end Test.class_method # => test.rb:4:in `<main>': undefined method

    `class_method' for Test:Class (NoMethodError) # Did you mean? class_eval メソッドがないよという例外が発生 ちなみに、メソッドがないと...
  3. では、これは? 継承とミックスイン module NiceFeature def method1 p "module method!" end

    end class Parent def method1 p "parent method!" end end class Test < Parent include NiceFeature end test = Test.new test.method1
  4. ミックスインされたモジュールのメソッドが優先して呼び出される 継承とミックスイン module NiceFeature def method1 p "module method!" end

    end class Parent def method1 p "parent method!" end end class Test < Parent include NiceFeature end test = Test.new test.method1 # => "module method!"
  5. Rubyのメソッドの見つけ方 ちなみにmethod_missingは メソッドを上まで探して、見つからなければ、 再度レシーバのクラスからmethod_missingの実装を上に探す ノート:  Class < Module < Object

    < Kernel < BasicObject                ↑           method_missingがデフォルトで実装されていて、           例外を生成
  6. では、これは? 継承とミックスインとsuperメソッド module NiceFeature def method1 p "module method!" end

    end class Parent def method1 p "parent method!" end end class Test < Parent include NiceFeature def method1 super end end test = Test.new test.method1
  7. 継承階層通り、ミックスインされたモジュールのメソッドが優先されて呼び出される 継承とミックスインとオーバーライド module NiceFeature def method1 p "module method!" end

    end class Parent def method1 p "parent method!" end end class Test < Parent include NiceFeature def method1 super end end test = Test.new test.method1 # => "module method!"
  8. 親クラスにないメソッドのsuperメソッド呼び出し メソッドを探して見つからなければmethod_missingを呼び出す super呼び出しによるものかもチェックしてくれている method_missingのオーバーライドは気をつけよう(※Effective Ruby 項目30) class Test def method1

    super end end test = Test.new test.method1 # => test.rb:3:in `method1': super: no superclass method `method1' for #<Test:0x007fb699008370> (NoMethodError) # => Did you mean? method # => methods # => from test.rb:8:in `<main>'