# = promoteself.rb
#
# == Copyright (c) 2005 Thomas Sawyer
#
#   Ruby License
#
#   This module is free software. You may use, modify, and/or redistribute this
#   software under the same terms as Ruby.
#
#   This program is distributed in the hope that it will be useful, but WITHOUT
#   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#   FOR A PARTICULAR PURPOSE.
#
# == Author(s)
#
# * Thomas Sawyer

# Author::    Thomas Sawyer
# Copyright:: Copyright (c) 2005 Thomas Sawyer
# License::   Ruby License

# = PromoteSelf
#
# PromoteSelf converts a module's class methods into instance methods
# such that the first parameter is passed self at the instance level.
# This promotes DRY programming when wishing to offer both an inheritable
# and a module callable procedure.
#
# == Usage
#
#   module MyModule
#     extend PromoteSelf
#     def self.jumble( obj, arg )
#       obj + arg
#     end
#   end
#
#   class String
#     include MyModule
#   end
#
#   MyModule.jumble( "Try", "Me" )  #=> "TryMe"
#
#   "Try".jumble( "Me" )            #=> 'TryMe'
#

module PromoteSelf
  alias_method :singleton_method_added_promoteself, :singleton_method_added if defined?(singleton_method_added)
  def singleton_method_added( meth )
    d = %{
      def #{meth}(*args)
        #{self.name}.#{meth}(self,*args)
      end
    }
    self.class_eval d
    singleton_method_added_promoteself( meth ) if defined?(singleton_method_added_promoteself)
  end
end



#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#

=begin testing

  require 'test/unit'

  # fixture

  module MyModule
    extend PromoteSelf
    def self.jumble( obj, arg )
      obj + arg
    end
  end

  class String
    include MyModule
  end

  # test

  class TC_PromoteSelf < Test::Unit::TestCase

    def test01
      assert_equal( 'TryMe', MyModule.jumble( "Try", "Me" ) )
    end

    def test02
      assert_equal( 'TryMe', "Try".jumble( "Me" ) )
    end

  end

=end
