irb> puts(line) while line = gets
this is test line
[EOF]
NameError: undefined local variable or method `line’ for main:Object
from (irb):1
The Pickaxe says on page 354 that unless the expression (on the left of
the while) is not a block, then the loop gets executed ZERO or more
times. So it has to evaluate the condition BEFORE the expression, which
ought to assign a value to “line” (thus defining it).
The Pickaxe says on page 354 that unless the expression (on
the left of the while) is not a block, then the loop gets
executed ZERO or more times. So it has to evaluate the
condition BEFORE the expression, which ought to assign a
value to “line” (thus defining it).
Lexically, “puts line” comes first. Although “while line =
gets” is executed first and it does set /a/ (not /the/) line,
it’s not yet available for “puts”.
Note, usually you cannot rely on IRB when it comes to scoping and
local variables. It behaves differently than normal Ruby code. But in
this case it’s right:
robert@fussel ~
$ ruby -e ‘puts line if line = gets’
d
-e:1: undefined local variable or method `line’ for main:Object
(NameError)
robert@fussel ~
$ ruby -e ‘def t; puts line if line = gets; end; t’
d
-e:1:in t': undefined local variable or method line’ for main:Object
(NameError)
from -e:1
The reason, as has been pointed out already is that the assignment
appears after the read access. A solution is to use “and”:
robert@fussel ~
$ ruby -e ‘line = gets and puts line’
s
s
robert@fussel ~
$
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.