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

ruby-changes:26276

From: eregon <ko1@a...>
Date: Wed, 12 Dec 2012 06:45:06 +0900 (JST)
Subject: [ruby-changes:26276] eregon:r38333 (trunk): * iseq.c (rb_iseq_parameters): fix limit for optional arguments.

eregon	2012-12-12 06:44:49 +0900 (Wed, 12 Dec 2012)

  New Revision: 38333

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

  Log:
    * iseq.c (rb_iseq_parameters): fix limit for optional arguments.
    * test/ruby/test_keyword.rb: tests for above.
    * vm_core.h (struct rb_iseq_struct): update documentation
      with keyword arguments. [Bug #7540] [ruby-core:50735]

  Modified files:
    trunk/ChangeLog
    trunk/iseq.c
    trunk/test/ruby/test_keyword.rb
    trunk/vm_core.h

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38332)
+++ ChangeLog	(revision 38333)
@@ -1,3 +1,12 @@
+Wed Dec 12 06:43:37 2012  Benoit Daloze  <eregontp@g...>
+
+	* iseq.c (rb_iseq_parameters): fix limit for optional arguments.
+
+	* test/ruby/test_keyword.rb: tests for above.
+
+	* vm_core.h (struct rb_iseq_struct): update documentation
+	  with keyword arguments. [Bug #7540] [ruby-core:50735]
+
 Wed Dec 12 03:45:41 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* vm.c (vm_exec): pass exceptions while handling an exception.
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 38332)
+++ vm_core.h	(revision 38333)
@@ -241,20 +241,24 @@
      *        b1=(...), b2=(...), ..., bN=(...),  # optional
      *        *c,                                 # rest
      *        d1, d2, ..., dO,                    # post
-     *        &e)                                 # block
+     *        e1:(...), e2:(...), ..., eK:(...),  # keyword
+     *        **f,                                # keyword rest
+     *        &g)                                 # block
      * =>
      *
-     *  argc           = M
-     *  arg_rest       = M+N+1 // or -1 if no rest arg
-     *  arg_opts       = N+1   // or 0  if no optional arg
+     *  argc           = M                 // or  0 if no mandatory arg
+     *  arg_opts       = N+1               // or  0 if no optional arg
+     *  arg_rest       = M+N               // or -1 if no rest arg
      *  arg_opt_table  = [ (arg_opts entries) ]
-     *  arg_post_len   = O // 0 if no post arguments
-     *  arg_post_start = M+N+2
-     *  arg_block      = M+N + 1 + O + 1 // -1 if no block arg
+     *  arg_post_start = M+N+(*1)          // or 0 if no post arguments
+     *  arg_post_len   = O                 // or 0 if no post arguments
+     *  arg_keywords   = K                 // or 0 if no keyword arg
+     *  arg_block      = M+N+(*1)+O+K      // or -1 if no block arg
+     *  arg_keyword    = M+N+(*1)+O+K+(&1) // or -1 if no keyword arg/rest
      *  arg_simple     = 0 if not simple arguments.
      *                 = 1 if no opt, rest, post, block.
      *                 = 2 if ambiguous block parameter ({|a|}).
-     *  arg_size       = argument size.
+     *  arg_size       = M+N+O+(*1)+K+(&1)+(**1) argument size.
      */
 
     int argc;
Index: iseq.c
===================================================================
--- iseq.c	(revision 38332)
+++ iseq.c	(revision 38333)
@@ -1792,12 +1792,7 @@
 	    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_keyword != -1 ? iseq->arg_keyword :
-	iseq->arg_size;
-    if (iseq->arg_keyword != -1) r -= iseq->arg_keywords;
+    r = iseq->argc + iseq->arg_opts - 1;
     for (; i < r; i++) {
 	PARAM_TYPE(opt);
 	if (rb_id2str(PARAM_ID(i))) {
Index: test/ruby/test_keyword.rb
===================================================================
--- test/ruby/test_keyword.rb	(revision 38332)
+++ test/ruby/test_keyword.rb	(revision 38333)
@@ -94,6 +94,27 @@
     assert_equal([[1, 2, 3], "bar", 424242, {}], f7(1, 2, 3, str: "bar"))
   end
 
+  define_method(:f8) { |opt = :ion, *rest, key: :word|
+    [opt, rest, key]
+  }
+
+  def test_f8
+    assert_equal([:ion, [], :word], f8)
+    assert_equal([1, [], :word], f8(1))
+    assert_equal([1, [2], :word], f8(1, 2))
+  end
+
+  def f9(r, o=42, *args, p, k: :key, **kw, &b)
+    [r, o, args, p, k, kw, b]
+  end
+
+  def test_f9
+    assert_equal([1, 42, [], 2, :key, {}, nil], f9(1, 2))
+    assert_equal([1, 2, [], 3, :key, {}, nil], f9(1, 2, 3))
+    assert_equal([1, 2, [3], 4, :key, {}, nil], f9(1, 2, 3, 4))
+    assert_equal([1, 2, [3, 4], 5, :key, {str: "bar"}, nil], f9(1, 2, 3, 4, 5, str: "bar"))
+  end
+
   def test_method_parameters
     assert_equal([[:key, :str], [:key, :num]], method(:f1).parameters);
     assert_equal([[:req, :x], [:key, :str], [:key, :num]], method(:f2).parameters);
@@ -102,6 +123,9 @@
     assert_equal([[:key, :str], [:key, :num], [:keyrest, :h]], method(:f5).parameters);
     assert_equal([[:key, :str], [:key, :num], [:keyrest, :h], [:block, :blk]], method(:f6).parameters);
     assert_equal([[:rest, :r], [:key, :str], [:key, :num], [:keyrest, :h]], method(:f7).parameters);
+    assert_equal([[:opt, :opt], [:rest, :rest], [:key, :key]], method(:f8).parameters) # [Bug #7540] [ruby-core:50735]
+    assert_equal([[:req, :r], [:opt, :o], [:rest, :args], [:req, :p], [:key, :k],
+                  [:keyrest, :kw], [:block, :b]], method(:f9).parameters)
   end
 
   def test_lambda

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

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