From: "K.Kosako" Date: 2002-03-15T16:12:33+09:00 Subject: [ruby-dev:16411] block local var Version: 1.7 latest コンパイル時点で、ブロック変数かどうかの判定が 正しくない場合があると思います。 (ブロックがネストされているが、間に新規のスコープ(関数定義等)があるとき) パッチが大きいので、ruby-devにしました。 def foo; yield; end foo { |a| a = 10 def bar foo { p(defined?(a)) # => "local-variable(in-block)" } end bar } --- parse.y.orig Tue Mar 12 18:28:48 2002 +++ parse.y Fri Mar 15 16:01:16 2002 @@ -394,7 +394,7 @@ stmt : kALIAS fitem {lex_state = EXPR_F if (in_def || in_single) { yyerror("BEGIN in method"); } - local_push(); + local_push(1); } '{' compstmt '}' { @@ -1382,7 +1382,7 @@ primary : literal if (in_def || in_single) yyerror("class definition in method body"); class_nest++; - local_push(); + local_push(1); $$ = ruby_sourceline; } compstmt @@ -1403,7 +1403,7 @@ primary : literal $$ = in_single; in_single = 0; class_nest++; - local_push(); + local_push(1); } compstmt kEND @@ -1420,7 +1420,7 @@ primary : literal if (in_def || in_single) yyerror("module definition in method body"); class_nest++; - local_push(); + local_push(1); $$ = ruby_sourceline; } compstmt @@ -1438,7 +1438,7 @@ primary : literal $$ = cur_mid; cur_mid = $2; in_def++; - local_push(); + local_push(1); } f_arglist compstmt @@ -1465,7 +1465,7 @@ primary : literal | kDEF singleton dot_or_colon {lex_state = EXPR_FNAME;} fname { in_single++; - local_push(); + local_push(1); lex_state = EXPR_END; /* force for args */ } f_arglist @@ -4919,11 +4919,12 @@ static struct local_vars { int nofree; int cnt; int dlev; + struct RVarmap* dyna_vars; struct local_vars *prev; } *lvtbl; static void -local_push() +local_push(int dyna_init) { struct local_vars *local; @@ -4933,7 +4934,10 @@ local_push() local->cnt = 0; local->tbl = 0; local->dlev = 0; + local->dyna_vars = ruby_dyna_vars; lvtbl = local; + + if (dyna_init) ruby_dyna_vars = (struct RVarmap* )0; } static void @@ -4945,6 +4949,7 @@ local_pop() if (!lvtbl->nofree) free(lvtbl->tbl); else lvtbl->tbl[0] = lvtbl->cnt; } + ruby_dyna_vars = lvtbl->dyna_vars; free(lvtbl); lvtbl = local; } @@ -5007,7 +5012,7 @@ local_id(id) static void top_local_init() { - local_push(); + local_push(0); lvtbl->cnt = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0; if (lvtbl->cnt > 0) { lvtbl->tbl = ALLOC_N(ID, lvtbl->cnt+3); -- 小迫@ソフネック 渋谷区恵比寿1-15-1