
class Module

  # Returns an anonymous module with the specified methods
  # of the receiving module renamed.
  def clone_renaming( pairs )
    mod = self.dup
    pairs.each_pair{ |to_sym, from_sym|
      mod.class_eval{
        alias_method( to_sym, from_sym )
        undef_method( from_sym )
      }
    }
    return mod
  end

  # Returns an anonymous module with the specified methods
  # of the receiving module removed.
  def clone_removing( *meths )
    mod = self.dup
    methods_to_remove = meths
    methods_to_remove.each{ |m|  mod.class_eval{ remove_method m }  }
    return mod
  end

  # Returns an anonymous module with only the specified methods
  # of the receiving module intact.
  def clone_using( *methods )
    methods.collect!{ |m| m.to_s }
    methods_to_remove = instance_methods - methods
    mod = self.dup
    mod.class_eval{ methods_to_remove.each{ |m| undef_method m } }
    return mod
  end

end



#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#
=begin test

  require 'test/unit'

  class TCModule < Test::Unit::TestCase

    module M
      def f; 1; end
      def g; 2; end
    end

    class Remove
      include M.clone_removing( :g )
    end

    class Rename
      include M.clone_renaming( :q => :g )
    end

    class Use
      include M.clone_using( :f )
    end

    def test_removing
      assert( Remove.method_defined?(:f) )
      assert( ! Remove.method_defined?(:g) )
    end

    def test_renaming
      assert( ! Rename.method_defined?(:g) )
      assert( Rename.method_defined?(:f) )
      assert( Rename.method_defined?(:q) )
    end

    def test_using_2
      assert( ! Use.method_defined?(:g) )
      assert( Use.method_defined?(:f) )
    end

  end

=end
