こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Module#method_addedの挙動

すいません、Rubyのドキュメントを見ながら動作を追っていて、疑問に感じたので質問をさせてください。
Module#method_addedというメソッドが追加されたタイミングで動作するメソッドがあります。
定義場所がModuleクラスの中なので、Moduleにメソッドを追加したら、それがmethod_addedを呼び出すと思って試して見たのですが、何故かそうなりません。
何故なのか理由がわからないんですが、教えていただけないでしょうか?

------------------------------------------------------------------
class Object
def self.method_added(*_)
p self.class.name
p __method__
p _
end

def self.singleton_method_added(*_)
p self.class.name
p __method__
p _
end
end

class Module
def self.method_added(*_)
p self.class.name
p __method__
p _
end

def self.slngleton_method_added(*_)
p self.class.name
p __method__
p _
end
end

module Foo
def self.foo
end

def foo2
end
end

class Bar
def self.bar
end

def bar2
end
end
------------------------------------------------------------------
出力結果
------------------------------------------------------------------
"Class"
:singleton_method_added
[:bar]
"Class"
:method_added
[:bar2]
------------------------------------------------------------------
動作環境は、Mac
rubyのバージョンは2.4.0です。

ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]

投稿日時 - 2017-05-18 19:18:38

QNo.9330816

困ってます

質問者が選んだベストアンサー

インスタンスメソッドを「クラス#メソッド」、特異メソッドを「クラス.メソッド」と書きます。

すべてのクラスはクラス Class の子クラスであり、
Class の親クラス Module の子クラスでもあるので、
Module のプライベートメソッドであるとは、
module、class 文内で関数のように
レシーバなしでメソッドを呼び出せるということです。

また、特異クラスは継承ツリー上で必ず元クラスより下位になります。
つまり最初に特異メソッドがメソッド探索されます。

1 Object.method_added を定義する。これは特異メソッドなので、
フックする singleton_method_added がまだない。

2 Object.singleton_method_added の定義後すぐにそれをフックして、
同メソッドが呼ばれる

3 Module.method_added 定義をフックして
Object.singleton_method_added が呼ばれる

4 Module.singleton_method_added 定義をフックして
Object.singleton_method_added が呼ばれる

5 モジュール Foo はクラス Module のインスタンスで
モジュールは特異クラスを持たないので特異クラスのメソッド探索はない。
もし Module#singleton_method_added、Object#singleton_method_added
が定義されていたら、Foo.foo 定義をフックするが、
定義されていないので何もしない

6 同様に Foo#foo2 定義をフックする Module#method_added、
Object#method_added がないので何もしない

7 Bar.bar 定義をフックして Object.singleton_method_added が呼ばれる

8 Bar#bar2 定義をフックして Object.method_added が呼ばれる

典型的使い方: https://pastebin.com/myeP9uJq
include、extend どちらでも同じようにできます。

投稿日時 - 2017-05-27 10:58:04

お礼

なるほど、Rubyそこそこ触って来ていたつもりですが、こうやって追いかけていくとわからないところがまだまだ掘られて行きますね。
納得がいきました。
ありがとうございます。

投稿日時 - 2017-05-31 15:24:06

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)