From: "Brian Schröder" Date: 2005-11-19T00:41:50+09:00 Subject: Re: IO.lineno= not behaving as expected On 18/11/05, Belorion wrote: > What am I missing here (apologies if this is just my 7am brain fog > speaking): > > The contents of my file (test) are: > 1 > 2 > 3 > 4 > 5 > 6 > > f = File.open('test') > f.lineno = 4 > puts f.readline # <= This returns 1, instead of 4 as expected > > I'm trying to do fast lookups in a file based on line number, but this isn't > working like I expected it to. 1) What am I missing here? 2) If this is not > what lineno=() is designed for, then what is it supposed to be used for? 3) > is there another easy way for fast lookups by line#? Thanks. > > Hello Belorion, it is impossible to do a fast lookup by line without building an index first (i.e. loading everything into an array or hashing line-number to byte position) because the program has to count the number of newlines to the line. So the best would be to simply do DATA = File.read("file").split(/\n/) and use DATA[linenumber-1] to access the data. Try to restructure your program in such a way that it need not read the file repeatedly. You could even go overboard and create a multiton class that reads the file into memory and checks on each access if the file has changed. Something like this: (Untested) class DataFile @@files = {} def self.open(file) @@files[file] ||= DataFile.new(file) end def initialize(filename) @filename = filename reread() end def read(line) mt = File.mtime(@filename) reread() if not @mt or @mt < mt @mt = mt @data[line] end private def reread @data = File.read(@filename).split(/\n/) end private :new end But that was more for the fun of it. Brian -- http://ruby.brian-schroeder.de/ Stringed instrument chords: http://chordlist.brian-schroeder.de/