# Statement modifiers causing confusion

**URL:** <https://www.ruby-forum.com/t/statement-modifiers-causing-confusion/48510>\
**Category:** Ruby\
**Created:** [November 21, 2005, 6:05pm UTC](https://www.ruby-forum.com/t/statement-modifiers-causing-confusion/48510 "2005-11-21T18:05:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![djmccormick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/49beb7/32.png) [@djmccormick](https://www.ruby-forum.com/u/djmccormick)\
**Post date:** [November 21, 2005, 6:05pm UTC](https://www.ruby-forum.com/t/statement-modifiers-causing-confusion/48510/1 "2005-11-21T18:05:07Z")

</div>

I’m working my way through the second edition of the pickaxe and have  
encountered an example that doesn’t work as I’d expected.

while line = gets  
puts line.downcase  
end

That code made sense… it was then simplified to:  
puts line.downcase while line = gets

This doesn’t work the same, however. I get:  
02.07.rb:1: undefined local variable or method `line’ for main:Object  
(NameError)

The odd part (to me) is that the error isn’t spit out until after I’ve  
entered a line. In which order does the interpreter do it’s job? Even  
more perplexing is:  
line = ‘This will never be seen…’  
puts line.downcase while line = gets

Defining line solves the issue. So, it seems to me, gets is executed  
but something is erroring before the assignment to line… ? Any help  
in understanding would be greatly appreciated!

---

<div class="post-metadata">

**Author:** ![djmccormick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/49beb7/32.png) [@djmccormick](https://www.ruby-forum.com/u/djmccormick)\
**Post date:** [November 21, 2005, 6:29pm UTC](https://www.ruby-forum.com/t/statement-modifiers-causing-confusion/48510/2 "2005-11-21T18:29:23Z")

</div>

> > > > > “D” == Dustin McCormick [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

D\> while line = gets

When ruby see the assignement `=' it will think that `line’ is a  
variable.  
Then when it parse `gets’ and because it’s the first time than it seen  
it,  
it will resolved as a method call.

D\> puts line.downcase

at this step, ruby now that `line’ make reference to a variable

D\> end

D\> puts line.downcase while line = gets

When it parse this line : it find `line’ and this is the first time  
that  
it seen it and it’s not an assignement. For ruby it’s a method call

When it parse ‘line =’, this time line will be referenced as a variable

You can see it with something like this

moulon% cat b.rb  
#!/usr/bin/ruby  
def line  
“ABC”  
end

puts line.downcase while (line = gets).chomp != ‘123’  
puts line  
moulon%

moulon% ./b.rb  
XYZ  
abc  
ERT  
abc  
123  
123  
moulon%

The first reference is for the method #line, the 2 others for the  
variable  
`line’

D\> 02.07.rb:1: undefined local variable or method `line’ for main:Object  
D\> (NameError)

Here ruby is trying to say :

1. at compile time, it has not found a variable line when it parsed  
this  
part of the source and it has resolved `line’ as a method call

2. at runtime, it has not found a method #line

D\> line = ‘This will never be seen…’  
D\> puts line.downcase while line = gets

Here ruby has seen an affection before the while and it know that  
`line’  
make reference to a variable

Guy Decoux
