@shan (Shannon Skipper) I don't think this documentation definition covers the case described by OP.
proc { |a,| }
is not the same as proc { |a| }
, and is semantically equivalent of proc { |a,*| }
. I think it is reasonable to expect its arity
—and, by the way, parameters
, would behave as in latter, not as in former.
I think this would be reasonable (and might be useful for metaprogramming code that checks the signature of the passed callable object):
proc { |a| a }.call([1, 2, 3]) #=> [1, 2, 3]
proc { |a| }.arity #=> 1
proc { |a| }.parameters #=> [[:opt, :a]]
proc { |a, *| a }.call([1, 2, 3]) #=> 1
proc { |a, *| }.arity #=> -2
proc { |a, *| }.parameters #=> [[:opt, :a], [:rest, :*]]
proc { |a,| a }.call([1, 2, 3]) #=> 1, like the latter
proc { |a,| }.arity #=> 1, should be -2
proc { |a,| }.parameters #=> [[:opt, :a]], should be [[:opt, :a], [:rest, :*]]
Though, experimenting a bit more with it, there is a funny edge case:
define_method(:m1, &proc { |a| })
define_method(:m2, &proc { |a, *| })
define_method(:m3, &proc { |a,| })
p method(:m1) #<Method: Object#m1(a)>
p method(:m2) #<Method: Object#m2(a, *)>
p method(:m3) #<Method: Object#m3(a)> --- like 1, not like 2
...which is probably related to reported arity/parameters.