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/