#--
# NOTES:
#
#   First Class Methods
#
#   I think the best solution would be using the notation
#   <tt>::ameth</tt>. This would require some minor changes
#   to Ruby, but with few backward incompatabilites if
#   parantheticals revert back to the actual method invocation.
#   Although this later stipulation means capitalized methods
#   would not be accessible in this way b/c they would intefere with
#   constant lookup. It's a trade off.
#
#                   Current           Proposed           Alternate
#                   ----------------- ------------------ -------------------
#     Foo.Bar()     method call       method call        method call
#     Foo.Bar       method call       method call        method call
#     Foo.bar()     method call       method call        method call
#     Foo.bar       method call       method call        method call
#     Foo::Bar()    method call       method call        1st class method
#     Foo::Bar      constant lookup   constant lookup    constant lookup
#     Foo::bar()    method call       method call        1st class method
#     Foo::bar      method call       1st class method   1st class method
#
#   Then again this dosen't address bound versus unbound.
#
#   Which do you prefer?
#++

module Kernel

  # Easy access to method as objects, and they retain state!
  #
  #   def hello
  #     puts "Hello World!"
  #   end
  #   p method!(:hello)   #=> <Method: #hello>
  #
  def method!(s)
    ( @__methods__ ||= {} )[s] ||= method(s)
  end

end


class Module

  # Easy access to method as objects, and they retain state!
  #
  #   module K
  #     def hello
  #       puts "Hello World!"
  #     end
  #   end
  #   p K.instance_method!(:hello)   #=> <UnboundMethod: #hello>
  #
  # CAUTION! This will not work exactly right until class variable
  # lookup is fixed. Presently it is limited to the scope of the
  # current module/class.

  def instance_method!(s)
    #( @@__instance_methods__ ||= {} )[s] ||= instance_method(s)  # TODO when fixed
    ( @__instance_methods__ ||= {} )[s] ||= instance_method(s)
  end

end



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

  require 'test/unit'

  class TC_METHOD < Test::Unit::TestCase

    class TestWith
      def foo ; end
    end

    def test_method!
      t = TestWith.new
      assert_equal( t.method!(:foo).__id__, t.method!(:foo).__id__ )
      assert_not_equal( t.method(:foo).__id__, t.method(:foo).__id__ )
    end

  end

=end
