-PR-
解決済み

Module#method_addedの挙動

  • 困ってます
  • 質問No.9330816
  • 閲覧数77
  • ありがとう数1
  • 気になる数0
  • 回答数1
  • コメント数0

お礼率 63% (164/258)

すいません、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]
通報する
  • 回答数1
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.1
レベル7

ベストアンサー率 87% (7/8)

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

すべてのクラスはクラス 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 どちらでも同じようにできます。
お礼コメント
m_matsubara

お礼率 63% (164/258)

なるほど、Rubyそこそこ触って来ていたつもりですが、こうやって追いかけていくとわからないところがまだまだ掘られて行きますね。
納得がいきました。
ありがとうございます。
投稿日時 - 2017-05-31 15:24:06
-PR-
-PR-
このQ&Aで解決しましたか?
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,500万件のQ&Aを分析して最適な回答をご提案します。

-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


専門家があなたの悩みに回答!

-PR-

ピックアップ

-PR-
ページ先頭へ