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

ruby-changes:7678

From: matz <ko1@a...>
Date: Sun, 7 Sep 2008 03:40:01 +0900 (JST)
Subject: [ruby-changes:7678] Ruby:r19199 (trunk): * parse.y (f_block_optarg): allow default for block parameters as

matz	2008-09-07 03:39:36 +0900 (Sun, 07 Sep 2008)

  New Revision: 19199

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

  Log:
    * parse.y (f_block_optarg): allow default for block parameters as
      long as the value is primary.  a patch from Eric Mahurin
      <eric.mahurin at gmail.com> in [ruby-core:16880].

  Modified files:
    trunk/ChangeLog
    trunk/parse.y
    trunk/sample/test.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 19198)
+++ ChangeLog	(revision 19199)
@@ -1,3 +1,9 @@
+Sun Sep  7 03:37:05 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* parse.y (f_block_optarg): allow default for block parameters as
+	  long as the value is primary.  a patch from Eric Mahurin
+	  <eric.mahurin at gmail.com> in [ruby-core:16880].
+
 Sun Sep  7 01:07:10 2008  Yukihiro Matsumoto  <matz@r...>
 
 	* parse.y (yylex): "1.upto 2 {|i| p i }" should be syntax error.
Index: sample/test.rb
===================================================================
--- sample/test.rb	(revision 19198)
+++ sample/test.rb	(revision 19199)
@@ -296,6 +296,64 @@
 test_ok(f.call([42,55]) == [[42,55]])
 test_ok(f.call(42,55) == [42,55])
 
+f = lambda { |a, b=42, *c| [a,b,c] }
+test_ok(f.call(1      ) == [1,42,[  ]] )
+test_ok(f.call(1,43   ) == [1,43,[  ]] )
+test_ok(f.call(1,43,44) == [1,43,[44]] )
+
+f = lambda { |a, b=(a|16), *c, &block| [a,b,c,block&&block[]] }
+test_ok(f.call(8      )     == [8,24,[  ],nil] )
+test_ok(f.call(8,43   )     == [8,43,[  ],nil] )
+test_ok(f.call(8,43,44)     == [8,43,[44],nil] )
+test_ok(f.call(8      ){45} == [8,24,[  ],45 ] )
+test_ok(f.call(8,43   ){45} == [8,43,[  ],45 ] )
+test_ok(f.call(8,43,44){45} == [8,43,[44],45 ] )
+
+f = lambda { |a, b=42, *c, d| [a,b,c,d] }
+test_ok(f.call(1      ,99) == [1,42,[  ],99] )
+test_ok(f.call(1,43   ,99) == [1,43,[  ],99] )
+test_ok(f.call(1,43,44,99) == [1,43,[44],99] )
+
+f = lambda { |a, b=(a|16), &block| [a,b,block&&block[]] }
+test_ok(f.call(8   )     == [8,24,nil] )
+test_ok(f.call(8,43)     == [8,43,nil] )
+test_ok(f.call(8,43)     == [8,43,nil] )
+test_ok(f.call(8   ){45} == [8,24,45 ] )
+test_ok(f.call(8,43){45} == [8,43,45 ] )
+test_ok(f.call(8,43){45} == [8,43,45 ] )
+
+f = lambda { |a, b=42, d| [a,b,d] }
+test_ok(f.call(1   ,99) == [1,42,99] )
+test_ok(f.call(1,43,99) == [1,43,99] )
+test_ok(f.call(1,43,99) == [1,43,99] )
+
+f = lambda { |b=42, *c, &block| [b,c,block&&block[]] }
+test_ok(f.call(     )     == [42,[  ],nil] )
+test_ok(f.call(43   )     == [43,[  ],nil] )
+test_ok(f.call(43,44)     == [43,[44],nil] )
+test_ok(f.call(     ){45} == [42,[  ],45 ] )
+test_ok(f.call(43   ){45} == [43,[  ],45 ] )
+test_ok(f.call(43,44){45} == [43,[44],45 ] )
+
+f = lambda { |b=42, *c, d| [b,c,d] }
+test_ok(f.call(      99) == [42,[  ],99] )
+test_ok(f.call(43   ,99) == [43,[  ],99] )
+test_ok(f.call(43,44,99) == [43,[44],99] )
+
+f = lambda { |b=42, &block| [b,block&&block[]] }
+test_ok(f.call(  )     == [42,nil] )
+test_ok(f.call(43)     == [43,nil] )
+test_ok(f.call(43)     == [43,nil] )
+test_ok(f.call(  ){45} == [42,45 ] )
+test_ok(f.call(43){45} == [43,45 ] )
+test_ok(f.call(43){45} == [43,45 ] )
+
+f = lambda { |b=42, d| [b,d] }
+test_ok(f.call(   99) == [42,99] )
+test_ok(f.call(43,99) == [43,99] )
+test_ok(f.call(43,99) == [43,99] )
+
+
 a,=*[1]
 test_ok(a == 1)
 a,=*[[1]]
Index: parse.y
===================================================================
--- parse.y	(revision 19198)
+++ parse.y	(revision 19199)
@@ -673,6 +673,7 @@
 %type <node> paren_args opt_paren_args
 %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
 %type <node> mrhs superclass block_call block_command
+%type <node> f_block_optarg f_block_opt
 %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
 %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
 %type <node> block_param opt_block_param block_param_def f_opt
@@ -3206,9 +3207,41 @@
 		    }
 		;
 
-block_param	: f_arg ',' f_rest_arg opt_f_block_arg
+block_param	: f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
 		    {
 		    /*%%%*/
+			$$ = new_args($1, $3, $5, 0, $6);
+		    /*%
+			$$ = params_new($1, $3, $5, Qnil, escape_Qundef($6));
+		    %*/
+		    }
+		| f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args($1, $3, $5, $7, $8);
+		    /*%
+			$$ = params_new($1, $3, $5, $7, escape_Qundef($8));
+		    %*/
+		    }
+		| f_arg ',' f_block_optarg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args($1, $3, 0, 0, $4);
+		    /*%
+			$$ = params_new($1, $3, Qnil, Qnil, escape_Qundef($4));
+		    %*/
+		    }
+		| f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args($1, $3, 0, $5, $6);
+		    /*%
+			$$ = params_new($1, $3, Qnil, $5, escape_Qundef($6));
+		    %*/
+		    }
+                | f_arg ',' f_rest_arg opt_f_block_arg
+		    {
+		    /*%%%*/
 			$$ = new_args($1, 0, $3, 0, $4);
 		    /*%
 			$$ = params_new($1, Qnil, $3, Qnil, escape_Qundef($4));
@@ -3239,6 +3272,38 @@
 			$$ = params_new($1, Qnil,Qnil, Qnil, escape_Qundef($2));
 		    %*/
 		    }
+		| f_block_optarg ',' f_rest_arg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args(0, $1, $3, 0, $4);
+		    /*%
+			$$ = params_new(Qnil, $1, $3, Qnil, escape_Qundef($4));
+		    %*/
+		    }
+		| f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args(0, $1, $3, $5, $6);
+		    /*%
+			$$ = params_new(Qnil, $1, $3, $5, escape_Qundef($6));
+		    %*/
+		    }
+		| f_block_optarg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args(0, $1, 0, 0, $2);
+		    /*%
+			$$ = params_new(Qnil, $1, Qnil, Qnil,escape_Qundef($2));
+		    %*/
+		    }
+		| f_block_optarg ',' f_arg opt_f_block_arg
+		    {
+		    /*%%%*/
+			$$ = new_args(0, $1, 0, $3, $4);
+		    /*%
+			$$ = params_new(Qnil, $1, Qnil, $3, escape_Qundef($4));
+		    %*/
+		    }
 		| f_rest_arg opt_f_block_arg
 		    {
 		    /*%%%*/
@@ -4339,6 +4404,44 @@
 		    }
 		;
 
+f_block_opt	: tIDENTIFIER '=' primary_value
+		    {
+		    /*%%%*/
+			if (!is_local_id($1))
+			    yyerror("formal argument must be local variable");
+			shadowing_lvar($1);
+			arg_var($1);
+			$$ = NEW_OPT_ARG(0, assignable($1, $3));
+		    /*%
+			$$ = rb_assoc_new($1, $3);
+		    %*/
+		    }
+		;
+
+f_block_optarg	: f_block_opt
+		    {
+		    /*%%%*/
+			$$ = $1;
+		    /*%
+			$$ = rb_ary_new3(1, $1);
+		    %*/
+		    }
+		| f_block_optarg ',' f_block_opt
+		    {
+		    /*%%%*/
+			NODE *opts = $1;
+
+			while (opts->nd_next) {
+			    opts = opts->nd_next;
+			}
+			opts->nd_next = $3;
+			$$ = $1;
+		    /*%
+			$$ = rb_ary_push($1, $3);
+		    %*/
+		    }
+		;
+
 f_optarg	: f_opt
 		    {
 		    /*%%%*/

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

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