Dear,

Though mixins are a very nice alternative for multiple inheritance,
they do sometimes cause name crashes that are quite annoying.  In a
recent project I was working on, a design choice I made is that
everything would be destroyed with the method 'teardown'.  What I mean
is that connections are closed, files are closed, etc etc..  As I was
refactoring the code, I noticed two pieces of code that could  each be
put into their own module (factored out).  However this led to the fact
that both the class that included the module as well as the super class
of that class and the class itself had the method teardown.  I could've
chosen to rename the method inside the extracted module, but instead I
came up with quite an interesting and reusable pattern.

The idea is that if you have a module with certain methods, you rename
those methods to modulenameinlowercase_methodname in the module.  It is
important that for this to work, the module must be included in the
class after any methods with similar names have been defined.
(Preferably at the end of the class).

Here is the code to the module that contains the necessary
functionality:
###############################################################################
module Extensible
  def self.define_aliases(mod, cl, methods)
    methods.each do |name|
      mod_name = mod.name.split("::").last.downcase
      if cl.method_defined?(name)
        num = 1
        while cl.method_defined?("old_#{num}_#{name}")
          num += 1
        end
        old_name = "old_#{num}_#{name}"
        cl.module_eval %Q|
        alias #{old_name} #{name}
        def #{name}(*args)
          self.#{mod_name}_#{name} *args
          self.#{old_name} *args
        end
        |
      else
        cl.module_eval %Q|
        alias #{name} #{mod_name}_#{name}
        |
      end
    end
  end
end
###############################################################################

It is used as follows in a module that contains functionality that must
be mixed in:
###############################################################################
module A1
  def self.append_features(cl)
    super
    methods = %q{test}.split
    Util.define_aliases(self, cl, methods)
  end

  def a1_test
    puts "A1"
  end
end
###############################################################################
Examples:
###############################################################################
class B1
  def test
    puts "B1"
  end
end

class C1 < B1
  def test
    super
    puts "C1"
  end
  include A1
end
C1.new.test =>
A1
B1
C1
###############################################################################
class D1 < B1
  include A1
end
D1.new.test =>
A1
B1
###############################################################################
class E1
  include A1
end
E1.new.test =>
A1
###############################################################################
class B2
  def test
    puts "B2"
  end
end

class C2 < B2
  def test
    super
    puts "C2"
  end
  include A2
  include A1
end
C2.new.test =>
A1
A2
B2
C2
###############################################################################
class D2 < B2
  include A2
  include A1
end
D2.new.test =>
A1
A2
B2
###############################################################################
class E2
  include A2
  include A1
end
E2.new.test =>
A1
A2
###############################################################################

Of course this still needs to be extended to work with objects as well,
but I thought I would share this.

With regards,
Christophe