>>>>> "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