On Oct 15, 8:11 am, Yukihiro Matsumoto <m... / ruby-lang.org> wrote:

> If I knew traits before designing Ruby, I'd have chosen traits over
> modules. But that's the life.

I have to agree that traits are too much alike and yet too different
from modules to co-exist in the same language. However, I disagree
with this subsequent statement. Much of the benefit of traits can
still be had by overlaying the same concepts on Ruby's modules. In the
end I think the most important part is usability, not so much the
underlying implementation (as long as it is reasonably efficient, of
course). Moreover, I contend that if you are serious when you say, you
would have used traits instead of modules if he had known about them,
then you were fortunate not to have known, b/c modules are a more
powerful composition mechanism, despite their greater implementation
complexity.

To demonstrate my point here is Facets' module/traits.rb lib. I
improved it a fair bit yesterday --thanks to Robert and this thread.
I'd like others to have a look and provide any feedback. As you will
see in the code, I still have a couple questions about where to use
public vs. all instance methods (which leads me to question/thought
that I will bring up in another thread). Here you go...

  class Module

    # Combine modules.

    def +(other)
      base = self
      Module.new do
        include base
        include other
      end
    end

    # Subtract modules.
    #--
    # TODO Should this use all instance_methods, not just public?
    #++
    def -(other)
      case other
      when Array
        subtract = instance_methods(true) & other.collect{|m| m.to_s}
      when Module
        subtract = instance_methods(true) &
other.instance_methods(true)  # false?
      when String, Symbol
        subtract = instance_methods(true) & [other.to_s]
      end
      base = self
      Module.new do
        include base
        subtract.each{ |x| undef_method x }
      end
    end

    # Rename methods.

    def *(rename_map)
      base = self
      Module.new do
        include base
        rename_map.each do |from, to|
          alias_method to, from
          undef_method from
        end
      end
    end

    # Detect conflicts.
    #--
    # TODO All instance methods, or just public?
    #++
    def conflict?(other)
      c = []
      c += (public_instance_methods(true) &
other.public_instance_methods(true))
      c += (private_instance_methods(true) &
other.private_instance_methods(true))
      c += (protected_instance_methods(true) &
other.protected_instance_methods(true))
      c.empty ? false : c
    end

    #def conflict?(other)
    #  c = instance_methods & other.instance_methods
    #  c.empty ? false : c
    #end

    def public_conflict?(other)
      c = public_instance_methods(true) &
other.public_instance_methods(true)
      c.empty ? false : c
    end

    def private_conflict?(other)
      c = private_instance_methods(true) &
other.private_instance_methods(true)
      c.empty ? false : c
    end

    def protected_conflict?(other)
      c = protected_instance_methods(true) &
other.protected_instance_methods(true)
      c.empty ? false : c
    end

  end


Thanks,
T.