[前][次][番号順一覧][スレッド一覧]

ruby-changes:9002

From: nobu <ko1@a...>
Date: Fri, 5 Dec 2008 13:08:25 +0900 (JST)
Subject: [ruby-changes:9002] Ruby:r20538 (trunk): * iseq.c (rb_iseq_parameters): proc arguments are always optional.

nobu	2008-12-05 13:05:48 +0900 (Fri, 05 Dec 2008)

  New Revision: 20538

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20538

  Log:
    * iseq.c (rb_iseq_parameters): proc arguments are always optional.
    * proc.c (get_proc_iseq, rb_proc_parameters): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/iseq.c
    trunk/proc.c
    trunk/test/ruby/test_proc.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 20537)
+++ ChangeLog	(revision 20538)
@@ -1,3 +1,9 @@
+Fri Dec  5 13:05:45 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* iseq.c (rb_iseq_parameters): proc arguments are always optional.
+
+	* proc.c (get_proc_iseq, rb_proc_parameters): ditto.
+
 Fri Dec  5 12:38:48 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* compile.c (iseq_set_sequence): uses rb_compile_warning() for
Index: iseq.c
===================================================================
--- iseq.c	(revision 20537)
+++ iseq.c	(revision 20538)
@@ -1303,7 +1303,7 @@
 }
 
 VALUE
-rb_iseq_parameters(const rb_iseq_t *iseq)
+rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
 {
     int i, r, s;
     VALUE a, args = rb_ary_new2(iseq->arg_size);
@@ -1317,14 +1317,24 @@
 	a)
 
     CONST_ID(req, "req");
-    for (i = 0; i < iseq->argc; i++) {
-	rb_ary_push(args, PARAM(i, req));
+    CONST_ID(opt, "opt");
+    if (is_proc) {
+	for (i = 0; i < iseq->argc; i++) {
+	    PARAM_TYPE(opt);
+	    rb_ary_push(a, rb_id2name(PARAM_ID(i)) ? ID2SYM(PARAM_ID(i)) : Qnil);
+	    rb_ary_push(a, Qnil);
+	    rb_ary_push(args, a);
+	}
     }
+    else {
+	for (i = 0; i < iseq->argc; i++) {
+	    rb_ary_push(args, PARAM(i, req));
+	}
+    }
     r = iseq->arg_rest != -1 ? iseq->arg_rest :
 	iseq->arg_post_len > 0 ? iseq->arg_post_start :
 	iseq->arg_block != -1 ? iseq->arg_block :
 	iseq->arg_size;
-    CONST_ID(opt, "opt");
     for (s = i; i < r; i++) {
 	PARAM_TYPE(opt);
 	if (rb_id2name(PARAM_ID(i))) {
@@ -1340,9 +1350,19 @@
 	rb_ary_push(args, PARAM(iseq->arg_rest, rest));
     }
     r = iseq->arg_post_start + iseq->arg_post_len;
-    for (i = iseq->arg_post_start; i < r; i++) {
-	rb_ary_push(args, PARAM(i, req));
+    if (is_proc) {
+	for (i = iseq->arg_post_start; i < r; i++) {
+	    PARAM_TYPE(opt);
+	    rb_ary_push(a, rb_id2name(PARAM_ID(i)) ? ID2SYM(PARAM_ID(i)) : Qnil);
+	    rb_ary_push(a, Qnil);
+	    rb_ary_push(args, a);
+	}
     }
+    else {
+	for (i = iseq->arg_post_start; i < r; i++) {
+	    rb_ary_push(args, PARAM(i, req));
+	}
+    }
     if (iseq->arg_block != -1) {
 	CONST_ID(block, "block");
 	rb_ary_push(args, PARAM(iseq->arg_block, block));
Index: proc.c
===================================================================
--- proc.c	(revision 20537)
+++ proc.c	(revision 20538)
@@ -25,7 +25,7 @@
 VALUE rb_cBinding;
 VALUE rb_cProc;
 
-VALUE rb_iseq_parameters(const rb_iseq_t *iseq);
+VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
 
 static VALUE bmcall(VALUE, VALUE);
 static int method_arity(VALUE);
@@ -611,19 +611,21 @@
 }
 
 static rb_iseq_t *
-get_proc_iseq(VALUE self)
+get_proc_iseq(VALUE self, int *is_proc)
 {
     rb_proc_t *proc;
     rb_iseq_t *iseq;
 
     GetProcPtr(self, proc);
     iseq = proc->block.iseq;
+    if (is_proc) *is_proc = !proc->is_lambda;
     if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) {
 	NODE *node = (NODE *)iseq;
 	iseq = 0;
 	if (nd_type(node) == NODE_IFUNC && node->nd_cfnc == bmcall) {
 	    /* method(:foo).to_proc */
 	    iseq = get_method_iseq(node->nd_tval);
+	    if (is_proc) *is_proc = 0;
 	}
     }
     return iseq;
@@ -656,7 +658,7 @@
 VALUE
 rb_proc_location(VALUE self)
 {
-    return iseq_location(get_proc_iseq(self));
+    return iseq_location(get_proc_iseq(self, 0));
 }
 
 static VALUE
@@ -688,11 +690,12 @@
 static VALUE
 rb_proc_parameters(VALUE self)
 {
-    rb_iseq_t *iseq = get_proc_iseq(self);
+    int is_proc;
+    rb_iseq_t *iseq = get_proc_iseq(self, &is_proc);
     if (!iseq) {
 	return unnamed_parameters(proc_arity(self));
     }
-    return rb_iseq_parameters(iseq);
+    return rb_iseq_parameters(iseq, is_proc);
 }
 
 /*
@@ -1509,7 +1512,7 @@
     body = data->body;
     switch (nd_type(body)) {
       case NODE_BMETHOD:
-	return get_proc_iseq(body->nd_cval);
+	return get_proc_iseq(body->nd_cval, 0);
       case RUBY_VM_METHOD_NODE:
 	GetISeqPtr((VALUE)body->nd_body, iseq);
 	if (RUBY_VM_NORMAL_ISEQ_P(iseq)) break;
@@ -1547,7 +1550,7 @@
     if (!iseq) {
 	return unnamed_parameters(method_arity(method));
     }
-    return rb_iseq_parameters(iseq);
+    return rb_iseq_parameters(iseq, 0);
 }
 
 /*
Index: test/ruby/test_proc.rb
===================================================================
--- test/ruby/test_proc.rb	(revision 20537)
+++ test/ruby/test_proc.rb	(revision 20538)
@@ -677,17 +677,17 @@
   def test_parameters
     assert_equal([], proc {}.parameters)
     assert_equal([], proc {||}.parameters)
-    assert_equal([[:req, :a]], proc {|a|}.parameters)
-    assert_equal([[:req, :a], [:req, :b]], proc {|a, b|}.parameters)
+    assert_equal([[:opt, :a, nil]], proc {|a|}.parameters)
+    assert_equal([[:opt, :a, nil], [:opt, :b, nil]], proc {|a, b|}.parameters)
     assert_equal([[:opt, :a, :a], [:block, :b]], proc {|a=:a, &b|}.parameters)
-    assert_equal([[:req, :a], [:opt, :b, :b]], proc {|a, b=:b|}.parameters)
+    assert_equal([[:opt, :a, nil], [:opt, :b, :b]], proc {|a, b=:b|}.parameters)
     assert_equal([[:rest, :a]], proc {|*a|}.parameters)
-    assert_equal([[:req, :a], [:rest, :b], [:block, :c]], proc {|a, *b, &c|}.parameters)
-    assert_equal([[:req, :a], [:rest, :b], [:req, :c]], proc {|a, *b, c|}.parameters)
-    assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], proc {|a, *b, c, &d|}.parameters)
-    assert_equal([[:req, :a], [:opt, :b, :b], [:rest, :c], [:req, :d], [:block, :e]], proc {|a, b=:b, *c, d, &e|}.parameters)
-    assert_equal([[:req], [:block, :b]], proc {|(a), &b|}.parameters)
-    assert_equal([[:req, :a], [:req, :b], [:opt, :c, :c], [:opt, :d, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], proc {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) 
+    assert_equal([[:opt, :a, nil], [:rest, :b], [:block, :c]], proc {|a, *b, &c|}.parameters)
+    assert_equal([[:opt, :a, nil], [:rest, :b], [:opt, :c, nil]], proc {|a, *b, c|}.parameters)
+    assert_equal([[:opt, :a, nil], [:rest, :b], [:opt, :c, nil], [:block, :d]], proc {|a, *b, c, &d|}.parameters)
+    assert_equal([[:opt, :a, nil], [:opt, :b, :b], [:rest, :c], [:opt, :d, nil], [:block, :e]], proc {|a, b=:b, *c, d, &e|}.parameters)
+    assert_equal([[:opt, nil, nil], [:block, :b]], proc {|(a), &b|}.parameters)
+    assert_equal([[:opt, :a, nil], [:opt, :b, nil], [:opt, :c, :c], [:opt, :d, :d], [:rest, :e], [:opt, :f, nil], [:opt, :g, nil], [:block, :h]], proc {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) 
   end
 
   def pm0() end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]