# What's going on here? (Newbie question)

**URL:** <https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664>\
**Category:** Ruby\
**Created:** [June 7, 2006, 3:35am UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664 "2006-06-07T03:35:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![MBMBMB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8491ac/32.png) [@MBMBMB](https://www.ruby-forum.com/u/MBMBMB)\
**Post date:** [June 7, 2006, 3:35am UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664/1 "2006-06-07T03:35:56Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![MBMBMB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8491ac/32.png) [@MBMBMB](https://www.ruby-forum.com/u/MBMBMB)\
**Post date:** [June 7, 2006, 3:44am UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664/2 "2006-06-07T03:44:31Z")

</div>

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 S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://www.stok.ca/~mike/](http://www.stok.ca/~mike/)

The “`Stok’ disclaimers” apply.

---

<div class="post-metadata">

**Author:** ![MBMBMB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8491ac/32.png) [@MBMBMB](https://www.ruby-forum.com/u/MBMBMB)\
**Post date:** [June 7, 2006, 3:47am UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664/3 "2006-06-07T03:47:38Z")

</div>

Exactly what I was looking for, thank you.

---

<div class="post-metadata">

**Author:** ![MBMBMB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8491ac/32.png) [@MBMBMB](https://www.ruby-forum.com/u/MBMBMB)\
**Post date:** [June 7, 2006, 7:45am UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664/4 "2006-06-07T07:45:48Z")

</div>

On Jun 6, 2006, at 9:42 PM, Mike S. wrote:

> > 456  
> > rewind a file to the beginning, so:  
> > irb(main):004:0\> f.each {|line| puts line}
> 
> Mike S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [Mike Stok](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.

---

<div class="post-metadata">

**Author:** ![MBMBMB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8491ac/32.png) [@MBMBMB](https://www.ruby-forum.com/u/MBMBMB)\
**Post date:** [June 7, 2006, 8:22am UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664/5 "2006-06-07T08:22:29Z")

</div>

Logan C. 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

---

<div class="post-metadata">

**Author:** ![MBMBMB](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8491ac/32.png) [@MBMBMB](https://www.ruby-forum.com/u/MBMBMB)\
**Post date:** [June 7, 2006, 3:13pm UTC](https://www.ruby-forum.com/t/whats-going-on-here-newbie-question/62664/6 "2006-06-07T15:13:14Z")

</div>

On Jun 6, 2006, at 11:43 PM, Logan C. 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.
