4 ms·
The major problem with block variables in ruby is that if you do something like x = 4 1.upto(5) do |x| puts x end puts "after the block x
by fendale 18y ago
The major problem with block variables in ruby is that if you do something like
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!
- Tichy 18y agotrue, but for this it would be fine(?): 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?
- fendale 18y agoYes I think so - your example will still print "after the block x is 5", but in that case that probably is what you would expect. 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 ...
- KirinDave 18y agoThe problem is that Ruby's scoping rules aren't consistent. Sometimes it appears lexically scoped, but sometimes it acts dynamically scoped. Sometimes this leads to funny looking code (if you know to avoid it) or truly inscrutable bugs (if you don't).
- gunderson 18y agoThat is what I'd expect. 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 end
- DougBTX 18y agoNormally you'd expect the parameter of a block to be a new variable, not to grab a variable from another scope and use that instead. So the "expected" value is 4, since x = 4 on the first line. You'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 end
- gunderson 18y agoYou're right, and that is the behavior in Ruby 1.9. I 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.