While modifiers have a scoping bug?!

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).

This will work, but shouldn't be necessary:

line = nil
puts(line) while line = gets

Any insight would be much appreciated!!!

···

--
Posted via http://www.ruby-forum.com/\.

puts(line) while line = gets

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".

line = nil
puts(line) while line = gets

Now it's the same "line"...

gegroet,
Erik V. - http://www.erikveen.dds.nl/

Erik already answered but I'll throw in my two cents. The first assignment of a local variable also declares it. What this means is:

puts(line) while (declare line; line = gets)

line is not in scope for puts(line) yet. Ruby creates it's lexical scopes for local vars by looking top to bottom, left to right at _parse_ time.

···

On Jun 28, 2006, at 1:36 PM, Mr Beev wrote:

> 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).

This will work, but shouldn't be necessary:

line = nil
puts(line) while line = gets

Any insight would be much appreciated!!!

--
Posted via http://www.ruby-forum.com/\.

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

robert@fussel ~
$

Kind regards

robert

···

2006/6/28, Mr Beev <lumbaa@gmail.com>:

> 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).

This will work, but shouldn't be necessary:

line = nil
puts(line) while line = gets

Any insight would be much appreciated!!!

--
Have a look: Robert K. | Flickr