>>>>> "M" == Mauricio =?iso-8859-1?Q?Fern=E1ndez?= <Mauricio> writes: >> b = 12 >> 1.times { b := 2 } >> >> `b := 2' will create a new block variable which shadow the previous >> variable `b' M> matz said previously that in M> (0...10).each { |x| ... } M> the values would be assigned to x with ':=', that is, M> x = ... M> inside the block would use the local. Put otherwise, this is the same as M> the "make them all local" solution w.r.t. block parameters! I know this, but you don't have || in my example. M> i = 0 M> x = 'some value' M> (0...10).each do |i| M> x := 'surprise!' if i == 2 M> x = i # uses local after the := is run M> end M> x => 1 I don't see where is the problem pigeon% cat b.rb #!./ruby i = 0 x = 'some value' (0...10).each do |i| x := 'surprise!' if i == 2 x = i # uses local after the := is run p x end p x pigeon% pigeon% b.rb ./b.rb:4: warning: shadowing variable `i' ./b.rb:5: warning: shadowing variable `x' 0 1 2 3 4 5 6 7 8 9 "some value" pigeon% M> Having 'x = ...' meaning completely different things depending on the M> "execution context" makes me feel unsecure. Don't forget that I know "my" and its undocumented "features" :-) and I can avoid them :-))) To understand what it do (tLOCAL_ASGN is `:=') [...] | lhs tLOCAL_ASGN command_call { node_local($1); $$ = node_assign($1, $3); } [...] static void block_local(node) NODE *node; { if (nd_type(node) == NODE_LASGN || nd_type(node) == NODE_DASGN) { rb_warn("shadowing variable `%s'", rb_id2name(node->nd_vid)); rb_dvar_push(node->nd_vid, Qnil); nd_set_type(node, NODE_DASGN_CURR); node->nd_aid = 0; } } static void node_local(node) NODE *node; { if (!node) return; if (dyna_in_block()) { if (nd_type(node) == NODE_MASGN) { NODE *list = node->nd_head; while (list) { node_local(list->nd_head); list = list->nd_next; } if (node->nd_args && node->nd_args != (NODE *)-1) { block_local(node->nd_args); } } else { block_local(node); } } else { rb_warn("useless use of `:='"); } } * at compile time, the lhs is modified (and a block local variable is created) *after* ruby has parsed the rhs * at runtime, ruby first execute the rhs and then make the assignement (i.e. create a new block local variable) This give something similar to a let* pigeon% cat b.rb #!./ruby 2.times do |i| b = i 3.times do |i| b := b + i p "in #{b}" end p "out #{b}" end pigeon% pigeon% b.rb ./b.rb:4: warning: shadowing variable `i' ./b.rb:5: warning: shadowing variable `b' "in 0" "in 1" "in 2" "out 0" "in 1" "in 2" "in 3" "out 1" pigeon% Guy Decoux