Issue #5694 has been updated by Marc-Andre Lafortune.


Hi,

Yui NARUSE wrote:
> Revert r33921.
> 
> Revert "* proc.c (rb_proc_arity): Fix Proc#arity in case of optional arguments"

I just noticed this, as I think the mailing list didn't get this update (at least I didn't)

You sure seem to enjoy reverting my commits.

> Because following two reason:
> * Proc#arity's return value with optional arguments is not clear.

What exactly is not clear in the official doc: "If the block has optional arguments, return -n-1, where n is the number of mandatory arguments." ?

>   The optional argument for proc/lambda is Ruby 1.9 feature.
>   In 1.9, proc(a, b=1){} can receive 1 or more arguments.
>   But lambda(a, b=1){} can receive only 1 or two arguments.

I'm glad to see we agree on this.

>   r33921 breaks lambda's arity.

How so?

>   The spec arround optional arguments of proc/lambda needs more
>   discussion.

I don't think so, but if you do, maybe you can suggest something? Maybe you can say in what way you'd want to change the official documentation, and the reasons why you think the arity of lambda's should behave differently from the arity of the equivalent method?

> * No tests.
>   Add tests to test-all.

As per the commit message, they have been committed to Rubyspec. As per my previous posts, you are most welcome to duplicate these in test-all. This doesn't warrant a revert. As per my previous posts, I would again ask you not to revert my commits in trunk, I'll do that myself if need be.


BTW, I agree it would be nice to easily get the maximum number of parameters for methods and lambdas (as well as maximum number of non-ignored parameters for a proc). I'll throw in the idea that `arity_range` could return an infinity in the case of unlimited arguments:

    ->(*args){}.arity_range # => 0...Float::INFINITY ?
    ->(*args){}.arity_range.include?(42) # => true

I feel it's more useful than (0..-1), which is not a real range. We might as well only introduce `arity_max`, which could return -1, or even `nil` for unlimited arguments.

I'm less enthusiastic about `callable?` because:
1) it is not be able to easily/reliably distinguish between a lamba with many (but limited) number of optional arguments and one with unlimited number of arguments.
2) it doesn't give useful information for Procs. A `Proc{||}` is callable with 42 arguments, but these will be ignored.
3) it might give the impression that the validity of the parameters will be checked too

The `begin rescue` is not a good solution because there is no (easy and reliable) way to know if the ArgumentError is due directly to the calling of the lambda/proc/method, or from some code inside of it generating an ArgumentError.

In short, my vote goes to `arity_range` returning the <min_params .. max_params>, where max_params would always be non-negative, and would be Float::INFINITY for unlimited arguments.
----------------------------------------
Bug #5694: Proc#arity doesn't take optional arguments into account. 
http://redmine.ruby-lang.org/issues/5694

Author: Marc-Andre Lafortune
Status: Assigned
Priority: Normal
Assignee: Yukihiro Matsumoto
Category: 
Target version: 
ruby -v: -


Currently:

    ->(foo = 42){}.arity # => 0, should be -1

This is contrary to the documentation and to what we should expect from the equivalent method definition.

Fixed in trunk, requesting backport for the 1.9 line.



-- 
http://redmine.ruby-lang.org