From: Justin Collins Date: 2008-01-23T09:42:32+09:00 Subject: Re: why must I initialize this variable? matt neuburg wrote: > Justin Collins wrote: > > >> irb(main):001:0> puts "#{hi}" if false >> => nil >> irb(main):002:0> puts "#{hi}" if hi = "hello" >> NameError: undefined local variable or method `hi' for main:Object >> from (irb):2 >> from :0 >> > > Even weirder! Why does it work in the first case but not in the second. > If you're going to say that 'hi' is undefined, surely it was undefined > in line 001. Yet line 001 raised no error. > > So what's wrong with 002? It cannot be the 'puts "#{hi}"' part - you > just proved, with 001, that that part's okay. So apparently it is the > assignment part. Evidently a tailgating "if" refuses to auto-instantiate > a variable. That is what I'm attempting to get clear on. Is that a bug? > Is it expected behavior? m. > > Again, I am not 100% on this (interpreter implementors would know better) but it's because the first line does not actually evaluate the left hand side. In the second line, the left hand side is parsed and set aside, something like how a block is, (someone please correct me on this if I am wrong) pending the evaluation of the conditional: irb(main):001:0> a = lambda { puts "#{hi}" } => # irb(main):002:0> a.call if false => nil irb(main):003:0> a.call if true NameError: undefined local variable or method `hi' for main:Object from (irb):1 from (irb):3:in `call' from (irb):3 from :0 irb(main):004:0> a.call if hi = "hello" (irb):4: warning: found = in conditional, should be == NameError: undefined local variable or method `hi' for main:Object from (irb):1 from (irb):4:in `call' from (irb):4 from :0 irb(main):005:0> hi => "hello" So, I guess it is something of a scope issue. -Justin