Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active August 29, 2015 13:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/9163507 to your computer and use it in GitHub Desktop.
Save havenwood/9163507 to your computer and use it in GitHub Desktop.
Ask a method, lambda or proc for the range of arguments it can be called with from minimum to maximum.
module ArityRange
def arity_range
args = parameters.map &:first
req = args.count :req
opt = args.include?(:rest) ? Float::INFINITY : args.count(:opt)
keyreq = args.count :keyreq
keyopt = args.include?(:keyrest) ? Float::INFINITY : args.count(:key)
{arguments: req..req + opt, keywords: keyreq..keyreq + keyopt}
end
end
class Proc
include ArityRange
end
class Method
include ArityRange
end
class UnboundMethod
include ArityRange
end
require_relative 'arity_range'
# For example, #puts can take zero or more args.
method(:puts).arity_range
#=> {:arguments=>0..Infinity, :keywords=>0..0}
method(:==).arity_range
#=> {:arguments=>1..1, :keywords=>0..0}
->{ }.arity_range
#=> {:arguments=>0..0, :keywords=>0..0}
lambda { |x, y| }.arity_range
#=> {:arguments=>2..2, :keywords=>0..0}
proc { |x, y| }.arity_range
#=> {:arguments=>0..2, :keywords=>0..0}
def req_keyword_example(required:); end
method(:req_keyword_example).arity_range
#=> {:arguments=>0..0, :keywords=>1..1}
def keyword_example(required:, optional: true); end
method(:keyword_example).arity_range
#=> {:arguments=>0..0, :keywords=>1..2}
def opt_keyword_example(optional: true); end
method(:opt_keyword_example).arity_range
#=> {:arguments=>0..0, :keywords=>0..1}
def opt_keywords_example(optional: true, another: true); end
method(:opt_keywords_example).arity_range
#=> {:arguments=>0..0, :keywords=>0..2}
def double_splat_keyword_example(optional: true, **hash); end
method(:double_splat_keyword_example).arity_range
#=> {:arguments=>0..0, :keywords=>0..Infinity}
->(a, b = true, c:, d: true) { }.arity_range
#=> {:arguments=>1..2, :keywords=>1..2}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment