Cleaned it up a bit & added some tests to sample/test.rb.  Not sure where you guys prefer the unit tests to go.  Is there a specific policy?  Also, is it better to submit small patches like this to rubyforge or directly this list?

-Adam

Index: proc.c
===================================================================
--- proc.c      (revision 12228)
+++ proc.c      (working copy)
@@ -434,9 +434,9 @@
     GetProcPtr(self, proc);
     iseq = proc->block.iseq;
     if (iseq && BUILTIN_TYPE(iseq) != T_NODE) {
-       if (iseq->arg_rest == 0 && iseq->arg_opts == 0) {
-           return INT2FIX(iseq->argc);
-       }
+       if( iseq->arg_rest < 0 ) {
+               return INT2FIX(iseq->argc);
+       }    
        else {
            return INT2FIX(-iseq->argc - 1);
        }
Index: sample/test.rb
===================================================================
--- sample/test.rb      (revision 12228)
+++ sample/test.rb      (working copy)
@@ -1283,6 +1283,36 @@
 lambda(&method(:test_ok)).call(true)
 lambda(&block_get{|a,n| test_ok(a,n)}).call(true, 2)
 
+# Proc#arity
+test_ok( Proc.new {}.arity        ,  0 )
+test_ok( Proc.new {||}.arity      ,  0 )
+test_ok( Proc.new {|a|}.arity     ,  1 )
+test_ok( Proc.new {|a,b|}.arity   ,  2 )
+test_ok( Proc.new {|a,b,c|}.arity ,  3 )
+test_ok( Proc.new {|*a|}.arity    , -1 )
+test_ok( Proc.new {|a,*b|}.arity  , -2 )
+
+# Method#arity
+class C
+  def one;    end
+  def two(a); end
+  def three(*a);  end
+  def four(a, b); end
+  def five(a, b, *c);    end
+  def six(a, b, *c, &d); end
+end
+c = C.new
+test_ok( c.method(:one).arity   , 0 )
+test_ok( c.method(:two).arity   , 1 )
+test_ok( c.method(:three).arity , -1 )
+test_ok( c.method(:four).arity  , 2 )
+test_ok( c.method(:five).arity  , -3 )
+test_ok( c.method(:six).arity   , -3 )
+test_ok( "cat".method(:size).arity    , 0 )
+test_ok( "cat".method(:replace).arity , 1 )
+test_ok( "cat".method(:squeeze).arity , -1 )
+test_ok( "cat".method(:count).arity   , -1 )
+
 class ITER_TEST1
    def a
      block_given?


On 4/26/07, Adam Bozanich <adam.boz@gmail.com> wrote:

On 4/26/07, Mauricio Fernandez <mfp@acm.org > wrote:
On Thu, Apr 26, 2007 at 06:55:46PM +0900, Mauricio Fernandez wrote:
> $ ruby19 -v -e "p proc{}.arity"
> ruby 1.9.0 (2007-02-07 patchlevel 0) [i686-linux]
> 0
> $ ./ruby19 -v -e "p proc{}.arity"
> ruby 1.9.0 (2007-04-26 patchlevel 0) [i686-linux]
> -1
>
> However, the RDoc documentation attached to proc_arity still says that it
> should return 0, so there's a bug, either in the code (wrong iseq->argc ?) or
> in the docs (if the latter, the patch below should do).

It seems it's a regression after all; no time to fix it now, but I've found
when it happened:

ruby-trunk-12116$ ./ruby -v -e "p proc{}.arity"
ruby 1.9.0 (2007-03-21 patchlevel 0) [i686-linux]
0

ruby-trunk-12117$ ./ruby -v -e "p proc{}.arity"
ruby 1.9.0 (2007-03-21 patchlevel 0) [i686-linux]
-1


This makes arity behave like the docs specify for both method.arity and proc.arity.  I'm sure it's naive, but it seems to work.

-Adam

Index: proc.c
===================================================================
--- proc.c      (revision 12226)
+++ proc.c      (working copy)
@@ -434,11 +434,11 @@
     GetProcPtr(self, proc);
     iseq = proc->block.iseq;
     if (iseq && BUILTIN_TYPE(iseq) != T_NODE) {
-       if (iseq->arg_rest == 0 && iseq->arg_opts == 0) {
-           return INT2FIX(iseq->argc);
-       }
+       if( iseq->arg_rest < 0 ) {
+               return INT2FIX(iseq->argc);
+       }    
        else {
-           return INT2FIX(-iseq->argc - 1);
+           return INT2FIX(-(iseq->argc + 1));
        }
     }
     else {