From: Brian Candler Date: 2003-02-01T21:33:17+09:00 Subject: Re: Local variables & blocks On Sat, Feb 01, 2003 at 11:43:47AM +0000, Brian Candler wrote: > Aside: I'd still prefer block parameters to be properly local, because I'll > still end up using stupid names like > > myobject.thing { |local_i, local_j| ... use local_i,local_j ... } Actually I'm not quite sure whether the proposal is to fix that, or not. Matz wrote in 63100: | * block parameters are local to the block | * shadowing cause warnings | * no other way to make block local variables Does "shadowing" mean a block parameter having the same name as a local variable outside? And is Matz saying it will become a truly local value (which breaks backwards-compatibility?) e.g. x = 10 [1,2,3].each { |x| thisval = x } puts x A warning will be generated, but will the final value printed be 10 or 3? Personally, my vote goes for "10", despite this being a language change. (i.e. the warning is to tell people running old scripts that they might need to fix them, not to tell people writing new scripts that they must rename their formal parameters to avoid side-effects :-) In that case, the warning is really telling you that this script might not work the same under an older version of Ruby - if you rename your block formal parameters, you can make it more backwards-compatible. I don't mind that 'thisval' will have a value of 3 which persists beyond the block. This is IMO much better that the current situation, which says that whether or not 'thisval' persists depends on whether 'thisval' was defined earlier (which could have been hundreds of lines before). When looking at a couple of lines of code, I don't want to have to scan the rest of my program to work out what its semantics are :-) In practice this last bit is not so important though. If you are using any kind of accumulator then you are bound to have to initialise it outside the loop anyway: e.g. total = 0 [1,2,3].each { |x| total += x } in which case the behaviour is the same now. But it would be useful when setting flags within the loop ("found = true") to be tested outside. However, I think the biggest advantage of this change is removing an inconsistency in the language: people can't complain "variables defined within a block are local, so why can't I have local variables elsewhere?" The answer becomes simply: "if you really want to localise the scope of your variables, put that bit of code in a separate method" Thanks, Brian.