RubyのMethod探索の話

先日参加させていただいた Ruby Meetup KansaiRailsActiveRecordのソースを追っかけててどうしても ActiveRecord::Core.generated_feature_methods が何しているかわからないと相談させていただくと、なんとその日中に調べてブログにアップしていただきました。 kennyjのブログ(仮)

感謝、感謝。

ActiveRecord::Core.generated_feature_methods が何をしているかは kennyjさんのブログを参照ということにして、MixInの使い方がおもしろかったので、備忘録をかねてメモ。

今までは include した時点で Module にあるMethod が include した側に足されるイメージだったけど、どうやら違うみたいで、includeしたModuleがメソッド探索に含まれるのが正解みたい。

class Sample
  def self.before
    @before ||= begin
      mod = const_set(:Before, Module.new)
      include mod
      mod
    end
  end

  def self.mixin
    @mixin ||= begin
      mod = const_set(:Mixin, Module.new)
      include mod
      mod
    end
  end
end

Sample.before
Sample.mixin

Sample.mixin.module_eval { define_method(:abc) { "mixin" } }
Sample.new.abc                  # => "mixin"

# 同名のMethodをBeforeに定義しても後からincludeされた
# Mixinの方がメソッド探索上優先されるのでそちらが呼ばれる。
Sample.before.module_eval { define_method(:abc) { "before" } }
Sample.new.abc                  # => "mixin"

おそらく自分が使う事は無いと思うけど、Gemのソース読むときに役立つことがあるかも。