Hatena::Grouprubyist

Going My Ruby Way このページをアンテナに追加 RSSフィード

Ruby ロゴ (C) Ruby Association LLC

2012年05月16日(水)

モジュールとモジュールを合わせてみる

00:53 | モジュールとモジュールを合わせてみる - Going My Ruby Way を含むブックマーク はてなブックマーク - モジュールとモジュールを合わせてみる - Going My Ruby Way モジュールとモジュールを合わせてみる - Going My Ruby Way のブックマークコメント

module M1
  def foo ; :foo ; end
end

module M2
  def bar ; :bar ; end
end

M = M1 | M2    # モジュールとモジュールを合わせる
p M.class      #=> Module

class C
  include M    # 合わせたモジュールを include
end

c = C.new
p c.foo        #=> :foo
p c.bar        #=> :bar

という実験です。

モジュールとモジュールを合わせる前に以下のコードを入れれば実現できます。

class Module
  def |(other)
    Module.new.tap do |mod|
      mod.send :include, other
      mod.send :include, self
    end
  end  
end  

実際には、バッチリ継承関係ができちゃってます。

p M.ancestors #=> [M, M1, M2]

モジュール演算なんて高尚なものではなく、ただの遊びです。


M1M2 のインスタンスメソッドの重複を許さない場合を考えると以下。

class Module
  def +(other)
    Module.new.tap do |mod|
      dups = instance_methods & other.instance_methods
      dups.empty? or raise "duplicated method: #{dups}"
      mod.send :include, other
      mod.send :include, self
    end
  end  
end

Mx = M1 + M
RuntimeError: duplicated method: [:foo]