From: "David A. Black" Date: 2007-12-28T22:39:46+09:00 Subject: Re: Block-local variables - obsolete? Hi -- On Sun, 23 Dec 2007, Rick DeNatale wrote: > On Dec 22, 2007 7:39 PM, Ryan Davis wrote: >> >> On Dec 22, 2007, at 15:32 , murphy wrote: >> >>> Charles Oliver Nutter wrote: >>>> Only block parameters are now always local to the block; variables >>>> from >>>> enclosing scopes are still visible. The ; syntax, then, is to specify >>>> certain names should be forced local, rather than defering to the >>>> outer >>>> scope. >>> is this really the difference? both produce the "shadowing outer local >>> variable" warning: >> >> I _think_ what Charles was getting at is by forcing local you can't >> use the variable AFTER the block: >> >>> irb(main):004:0> (1..2).each do |n; m| m ||= 0; m += n; end >>> => 1..2 >>> irb(main):005:0> m >>> NameError: undefined local variable or method `m' for main:Object >> >> (but, that appears to be the case regardless of the semicolon) > > irb(main):001:0> m = 1 > => 1 > irb(main):002:0> (1..2).each {|n;m| m = n} > => 1..2 > irb(main):003:0> m > => 1 > irb(main):004:0> (1..2).each {|n| m = n} > => 1..2 > irb(main):005:0> m > => 2 > > Note how in this case the first block has a local declaration of m, > while the second does not, and changes the binding of m in the outer > scope. > > So the 'warning' about shadowing is telling you that. > > 1) in the case of a parameter, the binding is different than in 1.8 Hopefully anything that warns of a deprecation or change like that will disappear once we're at a stabler version (1.9.1?). > 2) In the case of the local, that there's a variable with the same > name, in an outer scope which would otherwise be visible within the > scope of the block. There's no reason for a warning, then. If you're using the "; x" construct, you're saying that you want a block-local x, whether or not there's an x outside the block. So you certainly don't need to be warned that there's an x outside the block. The whole point is that you don't want to have to worry about that, one way or the other. Also, the whole reason that we're getting this new syntax in the first place, as I understand it, is because people want a way to not worry about outer variables. I've even heard it talked about in terms of "What if you cut-and-paste a block?" The ";" thing handles that problem -- so certainly if you use it, you don't care about what's in the containing scope, and shouldn't be warned about it. I guess the ";" is the "anti-closure" operator, or something :-) In any case, it should just let us do our thing and not give the warning. Shadowing the outer variable fact, is a sign that the programmer's intentions have succeeded, so a warning is out of place. David -- Training for 2008! Ruby on Rails training by David A. Black/Ruby Power and Light, LLC: * Intro to Rails, New York, NY, February 4-7 2008 * Advancing With Rails, New York, NY, February 11-14 2008 Hosted by Exceed Education. See http://www.rubypal.com for details!