Forum: Ruby What's going on here? (Newbie question)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5ab63f350cb5ce72b372882561514a14?d=identicon&s=25 MB (Guest)
on 2006-06-07 03:35
In irb:

f = File.new('numbers.txt')
=> #<File:numbers.txt>

f.each {|line| puts line}
123
456
789
=> #<File:numbers.txt>

f.each {|line| puts line}
=> #<File:numbers.txt>

Why doesn't the second f.each work?
2ffac40f8a985a2b2749244b8a1c4161?d=identicon&s=25 Mike Stok (Guest)
on 2006-06-07 03:44
(Received via mailing list)
On 6-Jun-06, at 9:36 PM, MB wrote:

>
> f.each {|line| puts line}
> => #<File:numbers.txt>
>
> Why doesn't the second f.each work?

because as each iterates through the file it "consumes" the file
contents (well, it remembers how far it has got.)  You can usually
rewind a file to the beginning, so:

irb(main):001:0> f = File.new('numbers.txt')
=> #<File:numbers.txt>
irb(main):002:0> f.each {|line| puts line}
123
456
789
=> #<File:numbers.txt>
irb(main):003:0> f.pos
=> 12
irb(main):004:0>  f.each {|line| puts line}
=> #<File:numbers.txt>
irb(main):005:0> f.pos
=> 12
irb(main):006:0> f.rewind
=> 0
irb(main):007:0>  f.each {|line| puts line}
123
456
789
=> #<File:numbers.txt>

Note that some types of file can't be rewound.

Take a look at what the pos method does, and see if this makes sense.

Hope this helps,

Mike

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.
5ab63f350cb5ce72b372882561514a14?d=identicon&s=25 Matt Brown (Guest)
on 2006-06-07 03:47
(Received via mailing list)
Exactly what I was looking for, thank you.
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-06-07 07:45
(Received via mailing list)
On Jun 6, 2006, at 9:42 PM, Mike Stok wrote:

>> 456
> rewind a file to the beginning, so:
> irb(main):004:0>  f.each {|line| puts line}
>
> Mike Stok <mike@stok.ca>
> http://www.stok.ca/~mike/
>
> The "`Stok' disclaimers" apply.
>
>
>
>
>

I wonder if IO#each should be changed to automatically #rewind at the
beginning of #each (if possible). I have difficulty imagining a
situation where someone would purposely do
a = file.gets
file.each { ... }

But I can certainly imagine people iterating over a file multiple
times. OTOH this may be too magical.
0b561a629b87f0bbf71b45ee5a48febb?d=identicon&s=25 Dave Burt (Guest)
on 2006-06-07 08:22
(Received via mailing list)
Logan Capaldo wrote:
> I wonder if IO#each should be changed to automatically #rewind at the
> beginning of #each (if possible). I have difficulty imagining a
> situation where someone would purposely do
> a = file.gets
> file.each { ... }
>
> But I can certainly imagine people iterating over a file multiple
> times. OTOH this may be too magical.

Too magical. Streams are often one-way. If you need to read the same
data from the same stream more than once, usually the appropriate
method is to store the data in a variable to avoid that. Instead of:

  f.each {|s| foo }
  f.reset
  f.each {|s| bar }

This may often work better:

  data = f.read
  data.each {|s| foo }
  data.each {|s| bar }

Cheers,
Dave
7a74932c21f86a9f3a0a12d83f778134?d=identicon&s=25 Bryan Weatherly (Guest)
on 2006-06-07 15:13
(Received via mailing list)
On Jun 6, 2006, at 11:43 PM, Logan Capaldo wrote:

>>>
>>
>> => #<File:numbers.txt>
>> 456
>>
>>
>
What about using:

f = IO.readlines(file)

Then the entire file contents will be loaded line-by-line as an
array.  You wouldn't have to worry about rewinding the position in
the actual file.
This topic is locked and can not be replied to.