module Amenable
Constants
- VERSION
Public Instance Methods
amenable(name)
click to toggle source
# File lib/amenable.rb, line 41 def amenable(name) # identify method and way to dynamically redefine it if methods(false).include?(name) fn = method(name).unbind # rebind later to support subclassing definer = method(:define_singleton_method) elsif private_methods(false).include?(name) fn = method(name).unbind definer = ->(name, &block) do define_singleton_method(name, &block) private_class_method(name) end elsif private_instance_methods(false).include?(name) fn = instance_method(name) definer = ->(name, &block) do define_method(name, &block) private(name) end elsif protected_instance_methods(false).include?(name) fn = instance_method(name) definer = ->(name, &block) do define_method(name, &block) protected(name) end elsif instance_methods(false).include?(name) fn = instance_method(name) definer = method(:define_method) else raise NoMethodError end # rebuild method with Amenable wrapper definer.call(name) do |*args, &block| # bind method to instance or subclass, which is now available if fn.respond_to? :bind fn = fn.bind(self) end Amenable.call(fn, *args, &block) end name end
call(fn, *args, **kwargs, &block)
click to toggle source
# File lib/amenable.rb, line 6 def call(fn, *args, **kwargs, &block) unless fn.is_a?(Method) || fn.is_a?(Proc) raise ArgumentError, "expecting type Method or Proc, found: #{fn.class}" end rest = keyrest = false params = [] keys = [] fn.parameters.each do |type, name| case type when :req, :opt params << name when :key, :keyreq keys << name when :rest rest = true when :keyrest keyrest = true end end # remove excessive args args = args.slice(0, params.count) unless rest if !keys.empty? || keyrest # remove excessive keywords kwargs = kwargs.slice(*keys) unless keyrest fn.call(*args, **kwargs, &block) else fn.call(*args, &block) end end