From: nobu.nakada@... Date: 2003-06-03T10:24:22+09:00 Subject: [ruby-dev:20316] Re: local variable and local variable in block behave differently なかだです。 ruby-talkに戻るべきなのかも知れませんが、途中経過を説明するのが めんどくさいのでdevへ。 At Sat, 31 May 2003 00:43:02 +0900, Yukihiro Matsumoto wrote: > |> 1.times do > |> if false > |> a = "" > |> else > |> 1.times { a = "a" } > |> end > |> puts defined? a # => local-variable(in-block) > |> puts a # => nil > |> end > | > |OK, that's weird... I would have thought that the assignment to 'a' in the > |inner block would have bound to the 'a' brought into existence in the outer > |block, but it hasn't. > > Maybe a bug. Let me check. At Mon, 02 Jun 2003 22:23:17 +0900, まつもと wrote: > 「ブロックローカル変数の実際の初期化は最も近いブロックの先頭 > で行われる」ってのは良さげに聞こえますね。問題あるかな? 今のところ思い付くのは、local_variablesの動作が変わってしまうと いうことですが。 とりあえず、http://nokada.jin.gr.jp/ruby/test_unpassed_dvar.rb のテストは通るようになります。 * parse.y (cmd_brace_block, do_block, brace_block): initialize block variables at the beginning of the block. [ruby-talk:72521] Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.275 diff -u -2 -p -r1.275 parse.y --- parse.y 31 May 2003 09:11:12 -0000 1.275 +++ parse.y 2 Jun 2003 23:54:36 -0000 @@ -166,4 +166,5 @@ static struct RVarmap *dyna_push(); static void dyna_pop(); static int dyna_in_block(); +static NODE *dyna_init(); static void top_local_init(); @@ -646,9 +647,9 @@ cmd_brace_block : tLBRACE_ARG $1 = ruby_sourceline; } - opt_block_var + opt_block_var {$$ = ruby_dyna_vars;} compstmt '}' { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $4)); nd_set_line($$, $1); dyna_pop($2); @@ -1715,9 +1716,9 @@ do_block : kDO_BLOCK $1 = ruby_sourceline; } - opt_block_var + opt_block_var {$$ = ruby_dyna_vars;} compstmt kEND { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $4)); nd_set_line($$, $1); dyna_pop($2); @@ -1778,8 +1779,8 @@ brace_block : '{' $1 = ruby_sourceline; } - opt_block_var + opt_block_var {$$ = ruby_dyna_vars;} compstmt '}' { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $4)); nd_set_line($$, $1); dyna_pop($2); @@ -1790,8 +1791,8 @@ brace_block : '{' $1 = ruby_sourceline; } - opt_block_var + opt_block_var {$$ = ruby_dyna_vars;} compstmt kEND { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $4)); nd_set_line($$, $1); dyna_pop($2); @@ -5655,4 +5656,19 @@ dyna_in_block() { return (lvtbl->dlev > 0); +} + +static NODE * +dyna_init(node, pre) + NODE *node; + struct RVarmap *pre; +{ + struct RVarmap *post = ruby_dyna_vars; + NODE *var; + + if (!node || !post || pre == post) return node; + for (var = 0; post != pre && post->id; post = post->next) { + var = NEW_DASGN_CURR(post->id, var); + } + return block_append(var, node); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦