1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
module Facade
# The version of the facade library
FACADE_VERSION = '1.2.1'.freeze
# The facade method will forward a singleton method as an instance
# method of the extending class. If no arguments are provided, then all
# singleton methods of the class or module become instance methods.
#
# Existing instance methods are NOT overridden, but are instead ignored.
#
# Example:
#
# require 'facade'
#
# class MyString < String
# extend Facade
# facade File, :dirname, :basename
# end
#
# s = MyString.new('/home/djberge')
# s.basename # => 'djberge'
# s.dirname # => '/home'
#
def facade(klass, *methods)
methods = methods.flatten
if methods.empty? # Default to all methods
if klass.kind_of?(Class)
methods = klass.methods(false)
else
methods = klass.public_instance_methods(false)
end
end
# Convert all strings to symbols to stay sane between 1.8.x and 1.9.x
methods = methods.map{ |m| m.to_sym }
methods -= self.instance_methods.map{ |m| m.to_sym } # No clobber
methods.each do |methname|
define_method(methname){
if klass.kind_of?(Class)
meth = klass.method(methname)
else
meth = Object.new.extend(klass).method(methname)
end
if meth.arity.zero? # Zero or one argument
meth.call
else
meth.call(self)
end
}
end
end
end
|