M. Q. said:
IO.gets steps through a file one line at a time.
As does IO.foreach. And IO.foreach's block terminates naturally when
the end of the file is reached:
IO.foreach("data.txt") do |line|
puts line
end
I thought possibly setting IO.lineno to the line before the current
line that would work, but I think I just misunderstood what lineno
was for.
$ ri IO.lineno
-------------------------------------------------------------- IO#lineno
ios.lineno => integer
------------------------------------------------------------------------
Returns the current line number in _ios_. The stream must be opened
for reading. +lineno+ counts the number of times +gets+ is called,
rather than the number of newlines encountered. The two values will
differ if +gets+ is called with a separator other than newline. See
also the +$.+ variable.
f = File.new("testfile")
f.lineno #=> 0
f.gets #=> "This is line one\n"
f.lineno #=> 1
f.gets #=> "This is line two\n"
f.lineno #=> 2
-------------------------------------------------
The key line in the description is:
**lineno counts the number of times gets is called**
It's no different than if you wrote:
lineno = 0
IO.foreach("data.txt") do |line|
lineno += 1
puts "#{lineno}: #{line}"
if lineno==1
lineno = 30
end
end
data.txt:
---------
hello
world
goodbye
--output:--
1: hello
31: world
32: goodbye
lineno is just a counter--it has no affect on the actual file pointer,
which marks the location of the current position in the file.
Anyone know a good way to do this?
prev_lines = []
IO.foreach("data.txt") do |line|
if line =~ /good/
prev_lines.reverse_each do |prev_line|
if prev_line =~ /hel/
puts prev_line
prev_lines = []
end
end
end
prev_lines << line
end