I'm having trouble understanding my own ruby script at the moment. If I check the contents of the next position with peek
, intending not to move the position yet, using include?
, the position of my enumerator is moved to the next one anyway.
For example:
print @file.each_line.peek
if @file.each_line.peek.include? 'State'
...
outputs
State
but this:
if @file.each_line.peek.include? 'State'
print @file.each_line.peek
...
outputs
CO
The contents of my file look like
...
Extension Date
State
CO
COLORADO
...
I am opening this file in the following manner: @file = File.open(file)
and using the @file.each_line
enumerator.
To me, this looks like using @file.each_line.peek.include? 'State'
is actually causing the position to move by one. Does anyone know why this is and how I can avoid it?
Create a file called test.txt with the following contents:
Extension Date
State
CO
COLORADO
Create a file called test.rb with the following contents:
file = File.open('./test.txt')
until file.each_line.next.include? 'Extension Date' do ; end
print file.each_line.peek
if file.each_line.peek.include? 'State'
end
When you run with ruby test.rb
, you should get the output State
.
If you then move line 3 so that it is inside the if block, the output (for me) is CO
.
It's not the .include?
, it's how you get your enumerator (a new one each time). Observe:
@file.each_line.peek # => "Extension Date\n"
@file.each_line.peek # => "State\n"
@file.each_line.peek # => "CO\n"
@file.each_line.peek # => "COLORADO\n"
@file.each_line.peek # => "\n"
The problem here is that when each_line
is called, it reads a line. And since file position is maintained between invocations, the second time you call it, it reads one more line. And so on.
Get enumerator once and hold on to it.
enum = @file.each_line
enum.peek # => "Extension Date\n"
enum.peek # => "Extension Date\n"
enum.peek # => "Extension Date\n"
enum.peek # => "Extension Date\n"
enum.peek.include?('foo') # => false
enum.peek # => "Extension Date\n"