From Yukihiro Matsumoto <987637838.835665.2921.nullmailer / ev.netlab.zetabits.com> > | print "a: #{a}\n" # Name Error > | > | it will the first time compile the part between #{}. Because for this > |iteration a was never assigned, it don't exist and ruby resolve it as a > |function call. This is why it give an error. > > That's what's happening. > > But I feel it's a bug, or at most misfeature. eval() should execute > as if the evaluating string is embedded in the code, so that the error > in this case is not what I expect. But I found it's pretty hard to > fix. It will remain as it is until I reimplement the core in the > future version. Sorry. Probably, I could fix it. In this method, only values are cleared without removing dyna-var objects at the end of rb_yield_0, and used in the next rb_yield_0 call. It is not a good method because the argument "acheck" of rb_yield_0 is being referred to to do the decision of yield-call or proc/thread-call. It took two hours to write this "English" mail. [0,1].each {|n| print "n: #{n}\n" case n when 0 a = 0 print "a: #{a}\n" # => 0 when 1 b = 1 print "a: #{a}\n" # => "a: " (a == nil) print "b: #{b}\n" end } --- eval.c.orig Wed Apr 18 00:35:04 2001 +++ eval.c Thu Apr 19 18:16:38 2001 @@ -3601,17 +3601,47 @@ } } #else - if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) && - !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) { - struct RVarmap *vars = ruby_dyna_vars; + if ((block->flags & BLOCK_D_SCOPE) && ruby_dyna_vars) { + struct RVarmap *vars; - if (ruby_dyna_vars->id == 0) { - vars = ruby_dyna_vars->next; - rb_gc_force_recycle((VALUE)ruby_dyna_vars); - while (vars && vars->id != 0) { - struct RVarmap *tmp = vars->next; - rb_gc_force_recycle((VALUE)vars); - vars = tmp; + if (acheck) { /* acheck == true : proc_call or thread_yield */ + if (!FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) { + vars = ruby_dyna_vars; + if (vars->id == 0) { + vars = ruby_dyna_vars->next; + rb_gc_force_recycle((VALUE)ruby_dyna_vars); + while (vars && vars->id != 0) { + struct RVarmap *tmp = vars->next; + rb_gc_force_recycle((VALUE)vars); + vars = tmp; + } + } + } + } + else { /* acheck == false : normal yield */ + if (FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) { + /* copy dyna-vars-list for next yield */ + if (ruby_dyna_vars->next && ruby_dyna_vars->next->id != 0) { + vars = ruby_dyna_vars->next; + vars = new_dvar(vars->id, Qnil, vars->next); + block->dyna_vars = vars; + for (; vars; vars = vars->next) { + if (!vars->next || vars->next->id == 0) break; + vars->next = new_dvar(vars->next->id, Qnil, vars->next->next); + } + } + } + else { + /* clear dyna-vars value for next yield */ + vars = ruby_dyna_vars; + if (vars->id == 0) { + block->dyna_vars = vars = ruby_dyna_vars->next; + rb_gc_force_recycle((VALUE)ruby_dyna_vars); + while (vars && vars->id != 0) { + vars->val = Qnil; + vars = vars->next; + } + } } } } ---- K.Kosako