[ruby-core:115146] [Ruby master Misc#19971] Confusing arity of a Proc with implicit rest parameter

Issue #19971 has been reported by andrykonchin (Andrew Konchin). ---------------------------------------- Misc #19971: Confusing arity of a Proc with implicit rest parameter https://bugs.ruby-lang.org/issues/19971 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal ---------------------------------------- I've noticed that such proc `proc { |a,| }` has arity `1` that means 1 required parameter, but behaves like there is a rest parameter (`proc { |a, *| }`) that has arity `-2` (that means 1 required parameter + rest parameter). So I am wondering whether it's intentional behaviour and what the rational is behind it. -- https://bugs.ruby-lang.org/

Issue #19971 has been updated by shan (Shannon Skipper). Docs say it's intended, since #arity "returns -n-1, where n is the number of mandatory arguments, with the exception for blocks that are not lambdas and have only a finite number of optional arguments; in this latter case, returns n." A Proc in this case isn't a lambda, so it returns `n` rather than `-n-1`. Procs have loose arity, like blocks, unlike lambdas. ---------------------------------------- Misc #19971: Confusing arity of a Proc with implicit rest parameter https://bugs.ruby-lang.org/issues/19971#change-105062 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal ---------------------------------------- I've noticed that such proc `proc { |a,| }` has arity `1` that means 1 required parameter, but behaves like there is a rest parameter (`proc { |a, *| }`) that has arity `-2` (that means 1 required parameter + rest parameter). So I am wondering whether it's intentional behaviour and what the rational is behind it. -- https://bugs.ruby-lang.org/

Issue #19971 has been updated by zverok (Victor Shepelev). @shan 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): ```ruby 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: ```ruby 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. ---------------------------------------- Misc #19971: Confusing arity of a Proc with implicit rest parameter https://bugs.ruby-lang.org/issues/19971#change-105064 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal ---------------------------------------- I've noticed that such proc `proc { |a,| }` has arity `1` that means 1 required parameter, but behaves like there is a rest parameter (`proc { |a, *| }`) that has arity `-2` (that means 1 required parameter + rest parameter). So I am wondering whether it's intentional behaviour and what the rational is behind it. -- https://bugs.ruby-lang.org/

Issue #19971 has been updated by shan (Shannon Skipper). Ah, I see. Thanks for clarifying! FWIW, lambdas don't ack the implicit rest either. ---------------------------------------- Misc #19971: Confusing arity of a Proc with implicit rest parameter https://bugs.ruby-lang.org/issues/19971#change-105065 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal ---------------------------------------- I've noticed that such proc `proc { |a,| }` has arity `1` that means 1 required parameter, but behaves like there is a rest parameter (`proc { |a, *| }`) that has arity `-2` (that means 1 required parameter + rest parameter). So I am wondering whether it's intentional behaviour and what the rational is behind it. -- https://bugs.ruby-lang.org/
participants (3)
-
andrykonchin (Andrew Konchin)
-
shan (Shannon Skipper)
-
zverok (Victor Shepelev)