
class Module

  #

  def +( other )
    mod1 = other.clone
    mod2 = clone

    mod1.module_eval{
      include mod2
    }

    #methods = other.instance_methods(false)
    #methods.each{ |name|
    #  method = other.instance_method(name)
    #  mod.module_eval {
    #    define_method( name, &method )
    #  }
    #}
  
    mod1
  end

  #

  def -( other )
    mod = clone

    case other
    when Array
      subtract = instance_methods & other.collect{|m| m.to_s}
    when Module
      subtract = instance_methods & other.instance_methods(false)
    when String, Symbol
      subtract = instance_methods & [ other.to_s ]
    end

    mod.module_eval do
      subtract.each{|x| remove_method x }
    end

    mod
  end

  # Rename methods.

  def *( rename_map )
    module_eval do
      rename_map.each do |from, to|
        alias_method( to, from )
        remove_method from
      end
    end
    self
  end

end 



=begin test

  require 'test/unit'

  class TraitsTest < Test::Unit::TestCase

    module A
      def x; "x"; end
      def z; "zA"; end
    end

    module B
      def y; "y"; end
      def z; "zB"; end
    end

    Q = A + B
    R = A - B

    def test_add
      assert( Q )
      Q.extend Q
      assert_equal(  "x", Q.x )
      assert_equal(  "y", Q.y )
      assert_equal( "zB", Q.z )
    end

    def test_minus
      assert(R)
      R.extend R
      assert_equal( "x", R.x )
      assert_raises( NoMethodError ){ R.z }
    end

  end

=end

