Ios.gets doesn't seem to work as advertised

I’ve got the following script in a Win2000SP3 environment running Ruby
1.6.8:

[snip]
while rec = File.new(fullFileName).gets("\r\n")
puts "Record: "+rec
end

for a file whose content is say:

AAA
BBB
CCC

with \r\n as the record separator (determined by viewing with a hex
editor). What I expected is:

Record: AAA
Record: BBB
Record: CCC

What I got is:

Record: AAA
BBB
CCC
Record: AAA
BBB
CCC
[ad nauseum]

So it appears that IO$gets returns a array of “lines” again and again,
rather than each “line” successively, as described in Programming
Ruby.

The kernel$gets works by returning individual lines and recognizes the
\r\n delimiter automatically. I had to go to the IO version because I
wanted to read from multiple files and needed to know the name of the
file being read, which didn’t seem possible if I passed an array to
ARGV. Resetting ARGV with different filenames was flagged as an
error.

I don’t want to read the entire file into memory for several reasons.
My application may encounter excessively large files. Secondly, my
application runs in a thread that processes the latest records added
to the file and idles when there are no new records to be inspected.

Any suggestions?

TIA,
Richard

You’re re-opening the file each time and reading
the the whole (haven’t examined why) file.

This should do it …

File.open(‘test.dat’) do |fi|
while rec = fi.gets
puts "Record: " << rec
end
end

Record: AAA

Record: BBB

Record: CCC

daz

···

“Richard” RichardLMuller@comcast.net wrote:

I’ve got the following script in a Win2000SP3 environment running Ruby
1.6.8:

[snip]

while rec = File.new(fullFileName).gets(“\r\n”)
puts "Record: "+rec
end

[snip]

Any suggestions?

TIA,
Richard

Hi All,

I solved one part of my problem, i.e. how to loop through individual
lines in a given text file, by using IO.foreach, e.g.:

IO.foreach(fullFileName) { |rec| processRec(rec) }

That routine recognized the \r\n delimiter implicitly. However, it
surprised me by returning an empty record after the final char(s),
i.e. the delimiter. That wasn’t mentioned in The Pragmatic
Programmer’s Guide. Am I misinterpreting anything here?

For the second part, how to continually monitor a file to get the next
unread record or an “EOF” return code allowing the thread to wait and
again test for the availability of an unread record (appended by some
other thread), I think I need to access a Win32 routine. I’m going to
check that out now. If anyone has a suggestion about this approach,
I’d appreciate hearing about it.

Regards,
Richard

Hi Daz,

Thanks not only to the succint solution to my problem:

File.open(‘test.dat’) do |fi|
while rec = fi.gets
puts "Record: " << rec
end
end

but for your explanation of the flaw in my approach.

Regards,
Richard

I made a mistake in my post:

That routine recognized the \r\n delimiter implicitly. However, it
surprised me by returning an empty record after the final char(s),
i.e. the delimiter. That wasn’t mentioned in The Pragmatic
Programmer’s Guide. Am I misinterpreting anything here?

I forgot to look at the hex version of the file before posting the
above lament. It turns out the file had an extra \r\n pair at the
end, so it did include an empty record. Sorry for the false alarm.

Richard