From: David Alan Black Date: 2002-02-24T11:27:19+09:00 Subject: Re: Newbie question Hello -- On Sun, 24 Feb 2002, roktas wrote: > $FMT = "/\t/" > > # Only one hash for the field labels (not 2*n) > $labels = {} > > def parse_line(line, fmt=$FMT) > # No extra process for the present > line.chomp.strip(delim) > end > > def DB > def initialize(f) > # First create the $labels hash from the first line > $labels = ... > > # Other stuff filling the @tab array > ... > end > > ... > > def [](key) > @tab[key] > end > end > > def Record < Array > def initialize(line) > # Parse and create a new record > parse_line(line) > end > def [](key) > key if key.kind_of?Integer > $labels.index(key) if key.kind_of?String > # Raise something for invalid cases ? > end > end > > Well... (1) I don't want to use any global var ($labels), (2) Seperating > 'records' and 'whole database' (DB) would be fine. I'm not sure about (2). Somehow the Record has to know about the fields in the database. Here's one way to do it with relatively little overhead -- each Record has an instance variable which points to the relevant fields array (but doesn't duplicate that array). class TSDB < Array attr_reader :labels, :records SEP = "\t" def TSDB.parse_line(line, sep=SEP) line.chomp.strip.split(/#{sep}/) end class Record < Array attr_accessor :fields def initialize(line) concat(TSDB.parse_line(line)) end def [](key) at(@fields.index(key)) end end def initialize(f) fh = File.open(f, "r") @fields = TSDB.parse_line(fh.readline) push("Dummy 0th record") concat (fh.readlines.map do |line| r = Record.new(line) r.fields = @fields r end) end end # Based on same tsd.txt file as last time: t = TSDB.new("tsd.txt") p t[1]["field1"] # "one" p t[2]["field2"] # "orange" David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav