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, 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 {