From: "Matthias Wächter" Date: 2007-09-13T22:30:41+09:00 Subject: Scope Issues (avoid name clashes for block parameters) On 30.08.2007 16:22, Todd Benson wrote: > On 8/30/07, kazaam wrote: >> Why is a local variable my_new_array not working but just @ instance or $ global variables and why do I have >> initialize this varriable? I think you don't need this in ruby? But without initialisation it just shows nil? > > It's about scope. I'm sure the veterans here can give you a thorough > explanation, (and please pipe in here, because I don't want to spread > disinformation), but basically the block tries to retain its own scope > as best it can (from what I understand). So, new variables that are > not "swallowed" from the scope outside of the block need to be > initialized, and those initialized within the block don't get outside > of the block (what happens in Vegas stays in Vegas, blah blah). > > Simple example... > > irb(main):001:0> a = 1,2,3,4 > => [1, 2, 3, 4] > irb(main):002:0> a.each { |i| b = i } #nothing happens here outside of > the block for b > => [1, 2, 3, 4] > irb(main):003:0> b > NameError: undefined local variable or method `b' for main:object > > > Here's one that will make you think a little that is somewhat OT, but > demonstrates namespace danger... > > irb(main):001:0> a = 1,2,3,4 > => [1, 2, 3, 4] > irb(main):002:0> a.inject{ |s, a| s + a } > => 10 > irb(main):003:0> a > => 4 > > The a is not the accumulator, but it has changed even though the > method doesn't have a ! following it. These are the small > idiosyncrasies that we have to be aware of with namespace and scope. Is there something I can do to avoid name clashes for block parameters? f.e. standard: x="external" a= 1,2,3,4 a.each {|x| puts x*x} puts x # => 4 vs. clash avoision (note the exclamation mark): x="external" a= 1,2,3,4 a.each {|!x| puts x*x} puts x # => "external" - Matthias