Skip to content

Instantly share code, notes, and snippets.

@2called-chaos
Created January 23, 2014 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 2called-chaos/8571489 to your computer and use it in GitHub Desktop.
Save 2called-chaos/8571489 to your computer and use it in GitHub Desktop.
module Banana
# Provides low level support functionalities.
module Kernel
# Calls a method with the maximum possible amount of arguments.
#
# Ruby's arity telling is too inaccurate so we just try to call the method
# with everything we have and if this raises an ArgumentError we examine the
# maximum allowed amount of arguments and pass those.
#
# Dont believe me?
#
# ->(a, b = "") {}.arity
# => -2
# ->(a, *b) {}.arity
# => -2
#
# @param [Proc, Lambda, UnboundMethod] method The method object you want to call.
# This is typically an UnboundMethod but you can pass everything as long as it `respond_to?(:call)`
# @param args Arbitrary arguments which will passed to `method`
# @param [Proc] block Optional block which will be passed to `method`
def __call_method_like_proc method, *args, &block
sliced = false
method.call(*args, &block)
rescue ::ArgumentError => exception
# examine allowed amount of arguments
match = exception.message.match(/wrong number of arguments.+\(([0-9]+) for ([0-9]+)\)/)
if !sliced && match
if match[2] == "0"
args = []
elsif match[2].to_i != 0
args = args[0...match[2].to_i]
else
raise exception
end
sliced = true
retry
end
raise exception
end
module_function :__call_method_like_proc
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment