From c4e5ec23d3cea5fb991a4ff3b1da733168731864 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 3 Oct 2006 15:59:45 +0000 Subject: * parse.y (block_param): restrict block parameters to be local variables only. * test/ruby/test_iterator.rb (TestIterator::test_nested_iterator): update test suite to conform the last change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11075 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ lib/scanf.rb | 3 ++- parse.y | 51 +++++++++++++++++++++++++++++++++++++--------- sample/optparse/opttest.rb | 26 +++++++++++------------ sample/test.rb | 3 ++- test/ruby/test_iterator.rb | 2 +- 6 files changed, 65 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e423799d5..2959174c94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,12 @@ Tue Oct 3 21:04:29 2006 Yukihiro Matsumoto * parse.y (mlhs): simplifies the rule a bit. + * parse.y (block_param): restrict block parameters to be local + variables only. + + * test/ruby/test_iterator.rb (TestIterator::test_nested_iterator): + update test suite to conform the last change. + Tue Oct 3 02:31:13 2006 Yukihiro Matsumoto * eval.c (splat_value): use "to_splat" instead of "to_ary" to diff --git a/lib/scanf.rb b/lib/scanf.rb index 3d56e4aabd..87b7e98eeb 100644 --- a/lib/scanf.rb +++ b/lib/scanf.rb @@ -542,7 +542,8 @@ module Scanf @string_left = str @matched_count = 0 - @specs.each_with_index do |spec,@i| + @specs.each_with_index do |spec,i| + @i=i @last_spec_tried = spec @last_match_tried = spec.match(@string_left) break unless @last_match_tried diff --git a/parse.y b/parse.y index 3864f5aaf9..b3338f97a9 100644 --- a/parse.y +++ b/parse.y @@ -540,6 +540,7 @@ static void ripper_compile_error(struct parser_params*, const char *fmt, ...); %type f_optarg f_opt f_block_arg opt_f_block_arg %type assoc_list assocs assoc undef_list backref string_dvar %type for_var block_param opt_block_param block_param_def block_param0 +%type block_param1 bparam_post %type opt_bv_decl bv_decls bv_decl lambda f_larglist lambda_body %type brace_block cmd_brace_block do_block lhs none fitem %type mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post @@ -2856,7 +2857,37 @@ for_var : lhs | mlhs ; -block_param0 : mlhs_item +block_param1 : bv_decl + | tLPAREN block_param rparen + { + /*%%%*/ + $$ = $2; + /*% + $$ = dispatch1(mlhs_paren, $2); + %*/ + } + ; + +bparam_post : block_param1 + { + /*%%%*/ + $$ = NEW_LIST($1); + /*% + $$ = mlhs_add(mlhs_new(), $1); + %*/ + } + | bparam_post ',' block_param1 + { + /*%%%*/ + $$ = list_append($1, $3); + /*% + $$ = mlhs_add($1, $3); + %*/ + } + ; + + +block_param0 : block_param1 { /*%%%*/ $$ = NEW_LIST($1); @@ -2864,7 +2895,7 @@ block_param0 : mlhs_item $$ = mlhs_add(mlhs_new(), $1); %*/ } - | block_param0 ',' mlhs_item + | block_param0 ',' block_param1 { /*%%%*/ $$ = list_append($1, $3); @@ -2904,7 +2935,7 @@ block_param : block_param0 $$ = blockvar_add_block(blockvar_new($1), $4); %*/ } - | block_param0 ',' tSTAR lhs ',' mlhs_post ',' tAMPER lhs + | block_param0 ',' tSTAR lhs ',' bparam_post ',' tAMPER lhs { /*%%%*/ $$ = NEW_BLOCK_PARAM($9, NEW_MASGN($1, NEW_POSTARG($4,$6))); @@ -2931,7 +2962,7 @@ block_param : block_param0 $$ = blockvar_add_block($$, $6); %*/ } - | block_param0 ',' tSTAR ',' mlhs_post ',' tAMPER lhs + | block_param0 ',' tSTAR ',' bparam_post ',' tAMPER lhs { /*%%%*/ $$ = NEW_BLOCK_PARAM($8, NEW_MASGN($1, NEW_POSTARG(-1,$5))); @@ -2948,7 +2979,7 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new($1), $4); %*/ } - | block_param0 ',' tSTAR lhs ',' mlhs_post + | block_param0 ',' tSTAR lhs ',' bparam_post { /*%%%*/ $$ = NEW_MASGN($1, NEW_POSTARG($4,$6)); @@ -2964,7 +2995,7 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new($1), Qnil); %*/ } - | block_param0 ',' tSTAR ',' mlhs_post + | block_param0 ',' tSTAR ',' bparam_post { /*%%%*/ $$ = NEW_MASGN($1, NEW_MASGN($1, NEW_POSTARG(-1,$5))); @@ -2998,7 +3029,7 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new(Qnil), $2); %*/ } - | tSTAR lhs ',' mlhs_post + | tSTAR lhs ',' bparam_post { /*%%%*/ $$ = NEW_MASGN(0, NEW_POSTARG($2,$4)); @@ -3006,7 +3037,7 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new(Qnil), $2); %*/ } - | tSTAR lhs ',' mlhs_post ',' tAMPER lhs + | tSTAR lhs ',' bparam_post ',' tAMPER lhs { /*%%%*/ $$ = NEW_BLOCK_PARAM($7, NEW_MASGN(0, NEW_POSTARG($2,$4))); @@ -3023,7 +3054,7 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new(Qnil), Qnil); %*/ } - | tSTAR ',' mlhs_post + | tSTAR ',' bparam_post { /*%%%*/ $$ = NEW_MASGN(0, NEW_POSTARG(-1,$3)); @@ -3031,7 +3062,7 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new(Qnil), Qnil); %*/ } - | tSTAR ',' mlhs_post ',' tAMPER lhs + | tSTAR ',' bparam_post ',' tAMPER lhs { /*%%%*/ $$ = NEW_BLOCK_PARAM($6, NEW_MASGN(0, NEW_POSTARG(-1,$3))); diff --git a/sample/optparse/opttest.rb b/sample/optparse/opttest.rb index 683c450d57..e2c6d1e048 100644 --- a/sample/optparse/opttest.rb +++ b/sample/optparse/opttest.rb @@ -23,49 +23,49 @@ ARGV.options do # mandatory argument opts.on("-r", "--require=LIBRARY", String, "require the LIBRARY, before", - "executing your script") {|@library|} + "executing your script") {|lib|@library=lib} # optional argument opts.on("-i", "--inplace=[EXTENSION]", "edit ARGV files in place", # multiline description - "(make backup if EXTENSION supplied)") {|@inplace| @inplace ||= ''} + "(make backup if EXTENSION supplied)") {|inplace| @inplace = inplace || ''} - opts.on("-N=[NUM]", Integer) {|@number|} + opts.on("-N=[NUM]", Integer) {|num|@number=num} # additional class - opts.on("-t", "--[no-]time[=TIME]", Time, "it's the time") {|@time|} + opts.on("-t", "--[no-]time[=TIME]", Time, "it's the time") {|time|@time=time} # limit argument syntax opts.on("-[0-7]", "-F", "--irs=[OCTAL]", OptionParser::OctalInteger, - "specify record separator", "(\\0, if no argument)") {|@irs|} + "specify record separator", "(\\0, if no argument)") {|irs|@irs=irs} # boolean switch(default true) @exec = true - opts.on("-n", "--no-exec[=FLAG]", TrueClass, "not really execute") {|@exec|} + opts.on("-n", "--no-exec[=FLAG]", TrueClass, "not really execute") {|exec|@exec=exec} # array - opts.on("-a", "--list[=LIST,LIST]", Array, "list") {|@list|} + opts.on("-a", "--list[=LIST,LIST]", Array, "list") {|list|@list=list} # fixed size array - opts.on("--pair[=car,cdr]", Array, "pair") {|@x, @y|} + opts.on("--pair[=car,cdr]", Array, "pair") {|x,y|@x=x; @y=y} # keyword completion opts.on("--code=CODE", CODES, CODE_ALIASES, "select coding system", - "("+CODES.join(",")+",", " "+CODE_ALIASES.keys.join(",")+")") {|@code|} + "("+CODES.join(",")+",", " "+CODE_ALIASES.keys.join(",")+")") {|c|@code=c} # optional argument with keyword completion - opts.on("--type[=TYPE]", [:text, :binary], "select type(text, binary)") {|@type|} + opts.on("--type[=TYPE]", [:text, :binary], "select type(text, binary)") {|t|@type=t} # boolean switch with optional argument(default false) - opts.on("-v", "--[no-]verbose=[FLAG]", "run verbosely") {|@verbose|} + opts.on("-v", "--[no-]verbose=[FLAG]", "run verbosely") {|v|@verbose=v} # easy way, set local variable - opts.on("-q", "--quit", "quit when ARGV is empty") {|@quit|} + opts.on("-q", "--quit", "quit when ARGV is empty") {|q|@quit=q} # adding on the fly opts.on("--add=SWITCH=[ARG]", "add option on the fly", /\A(\w+)(?:=.+)?\Z/) do |opt, var| - opts.on("--#{opt}", "added in runtime", &eval("proc {|@#{var}|}")) + opts.on("--#{opt}", "added in runtime", &eval("proc {|x|@#{var}=x}")) end opts.on_head("specific options:") diff --git a/sample/test.rb b/sample/test.rb index a5026d49c8..a32dbcbec2 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -846,8 +846,9 @@ def tt } end +i=0 tt{|i| break if i == 5} -test_ok(i == 5) +test_ok(i == 0) def tt2(dummy) yield 1 diff --git a/test/ruby/test_iterator.rb b/test/ruby/test_iterator.rb index 8a2b81693b..0db54302f5 100644 --- a/test/ruby/test_iterator.rb +++ b/test/ruby/test_iterator.rb @@ -52,7 +52,7 @@ class TestIterator < Test::Unit::TestCase def test_nested_iterator i = 0 tt{|i| break if i == 5} - assert_equal(5, i) + assert_equal(0, i) assert_raises(ArgumentError) do tt3{} -- cgit v1.2.3