3 ms·
It doesn't seem evil to me at all, it is exactly what I would expect. a = 1 for a in 1..2 b = a end p a >> 2 It seems natural that that would ch
by mattmcknight 18y ago
It doesn't seem evil to me at all, it is exactly what I would expect.
a = 1
for a in 1..2
b = a
end
p a
>> 2
It seems natural that that would change the value of "a", I wouldn't expect a for loop to create a new scoping context. The example with putting a closure into the array is also what I would expect.
I am not sure what programming language has the scoping rules he expects, but for me there's nothing to see here, moving along...
- sandal 18y agoRuby has block local scoping. It's not the case where you set a beforehand that matters, but when you don't. For example: >> (1..2).each { |i| p i } 1 2 => 1..2 >> i NameError: undefined local variable or method `i' >> for i in 1..2; p i; end 1 2 => 1..2 >> i => 2 So the real danger comes in here: >> procs = [] => [] >> (1..2).each { |i| procs << lambda { i } } => 1..2 >> procs.map { |e| e.call } => [1, 2] >> procs2 = [] => [] >> for i in 1..2; procs2 << lambda { i }; end => 1..2 >> procs2.map { |e| e.call } => [2, 2] Which seems better to you? If you're not coming from Ruby, I can understand how reading the first part of this entry might make you think "what's the big deal", but if you read on, you'll see an extended version of what I've shown above. It's the closures that make this issue complicated.
- mattmcknight 18y agoIt's the Ruby 1.9 each implementation that seems confusing to me. I don't have a natural feeling about a new scope being created for local variables first referenced in that block. I am much more used to method, object, and class level scoping. In most of the simple Ruby code I write, you can tell the scope of a variable by looking at it's name. I can see where you might need the block scoping with closures, but I actually find the second example more logical. In the first example, I can't imagine which memory address would still be holding the 1, and what it's name would be. I can easily see how the value at i would be 2.
- _pius 18y agoTo me the following is highly surprising: #assuming a is unbound at this point for a in 1..2 b = 2 end p a >> 2 I expect "a" to be free outside the loop in Ruby.
- mattmcknight 18y agoIn most of the OO languages I've used, declaring a variable in a loop header scopes it to the method, not the loop.
- SwellJoe 18y agofor my $a (1..2) { $b = 2; } print $a; Prints nothing. (Of course, with warnings or strict this complains about both $b and the second $a, as they're either never used or undefined.) Block scope is very nice. Maybe I don't use enough other OO languages to really grok why you'd want it any other way. What's the benefit to having method rather than block scope in such a context? I don't remember hating not having block scope in Python when I switched for about three or four years, but I didn't really use it in Perl at that point either, so I might miss it now that I do.