b = 12
1.times { b := 2 }
`b := 2' will create a new block variable which shadow the previous
variable `b'
matz said previously that in
(0...10).each { |x| ... }
the values would be assigned to x with ':=', that is,
x = ...
inside the block would use the local. Put otherwise, this is the same as
the "make them all local" solution w.r.t. block parameters!
I know this, but you don't have || in my example.
i = 0
x = 'some value'
(0...10).each do |i|
x := 'surprise!' if i == 2
x = i # uses local after the := is run
end
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%
Having 'x = ...' meaning completely different things depending on the
"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