x = 4
1.upto(5) do |x|
puts x
end
puts "after the block x is #{x}"
It will print: 1
2
3
4
5
after the block x is 5
That is probably not what you would expect! x = 4
1.upto(5) do |y|
x = y
puts x
end
puts "after the block x is #{x}
So the problem is only the parameter to the block?Maybe my head has just gone blank, but I cannot think of a way to get a local called 'x' inside that block that is in scope only within the block.
In Perl you would have done
my $x = 5;
foreach my $i in (1..5) {
my $x = $i;
...
}
And it would have given you a new 'block local' and left your original x alone, but I cannot think of how you can do the equivalent of 'my' in Ruby ...Sometimes this leads to funny looking code (if you know to avoid it) or truly inscrutable bugs (if you don't).
1.upto implies starting at 1... otherwise why would upto be called on 1?
If you want the behavior you expect, type:
x = 4
5.times do
x += 1
endYou'd expect these two examples to output the same number:
x = 1
my_fun do |x|
x = 5
end
puts x # => 5
and x = 1
my_fun do |y|
y = 5
end
puts x # => 1
where my_fun could be defined as: def my_fun
yield 2
endI posted the example I did so that those unfamiliar with Ruby would see that the parent was a contrived example to use upto in that context. Sure it's awkward b/c it's not the intended semantics of the upto method, hence the ambiguity.
Maybe an ideal language would not introduce that sort of ambiguity... I personally slightly perfer the 1.9 syntax.