Ruby Tidbit: Proc#arity


Quick Ruby quiz for you. Consider the following code:

proc {|arg1, arg2|}.arity # => 2
proc {|arg1|}.arity       # => 1
proc {|*args|}.arity      # => -1
proc {||}.arity           # => 0
proc {}.arity             # => ???

What's the output of the last line?

Ha! Trick question.

The answer is: it depends on what version of Ruby you're running.

In recent 1.9.x versions of Ruby, you'll see that it returns 0, as you might initially have expected. In Ruby 1.8, you get a -1 return value, which is the same as saying there's a splat parameter in the first position (side note: an arity of -n means that there is a splat parameter in position n).

There's a rich history of discussion around precisely how Proc#arity should behave. On one hand, it's true that while a lambda is strict about the number of parameters it receives, a proc doesn't really care. On the other hand, when I use Proc#arity, I'm less concerned with what I can send without raising an ArgumentError, and more concerned with what the Proc (or method; the Method class also has an #arity method) will actually use.

If you'd like to read some more discussion about Proc#arity, and some of the complexities involved in deciding what it really should return, take a look at this thread on the Ruby issue tracker.

There are some really solid suggestions there for what a post-Ruby-2.0 version of Proc#arity might look like.

comments powered by Disqus