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

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

170
March 21, 2017

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

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