From: ahoward Date: 2003-01-29T01:41:55+09:00 Subject: Re: Use mulit-dim. Arrays? [Questions from a Ruby Newbie (file io and d ata structures)...] On Wed, 29 Jan 2003 christopher.j.meisenzahl@citicorp.com wrote: > I've got the file IO hammered out. I think I can read each line into a string > and then parse into an array using: one of the things that i LOVE, LOVE, LOVE about ruby is that it's so easy to write an object to encapsulate common scripting tasks. there were some slides floating around somewhere in which matz said something to the effect that 'what's good for programming is good for scripting', refering to object-oriented programming. for example, i have a similar problem to yours, where we have all these silly config files floating around, each with a slightly different syntax - you _could_ parse each one out in every script, or you could write a class which does this for you, for example (overly simplistic) say you have two config files FILE : 'in.csv' ----CUT---- # a comment col1,col2,col3 a,b,c d,e,f g,h # another comment j ----CUT---- and FILE : 'printers.txt' ----CUT---- # type name hp bugs xerox fg-color ----CUT---- 'in.csv' is a comma-separated values file, while 'printers.txt' is a tab-delimited file. both could contain comments and empty lines. here's a silly parser which handles both types #!/usr/bin/env ruby class Cfg < Array DEFAULT_DELIM = ',' DEFAULT_COMMENT = '#' attr_reader :max_cols attr_accessor :comment attr_accessor :delim def initialize path, delim = DEFAULT_DELIM, comment = DEFAULT_COMMENT @max_cols = 0 @delim = delim @comment = comment comment_pat = %r{#{comment}.*$} lines = IO.readlines path lines.each do |line| line.strip! next if line.size == 0 line[comment_pat] = '' row = line.split delim next unless row.size > 0 @max_cols = [row.size, @max_cols].max self << row end end def to_s (map {|r| r.join (delim)}).join ($/) << $/ end def pad value = nil map! {|r| r.fill value, r.size...max_cols} end end if $0 == __FILE__ csv = Cfg.new 'in.csv' print csv csv.pad '!' print csv printers = Cfg.new 'printers.txt', "\t" print printers end the program outputs this : /usr/home/howardat/eg/ruby > ./Csv.rb col1,col2,col3 a,b,c d,e,f g,h j col1,col2,col3 a,b,c d,e,f g,h ,! j,!,! hp bugs xerox fg-color my point is simply that, although you can do things really tersely and slickly in ruby (as you can in perl) i think it's ability to use OO programming for every day tasks is where it really shines. if you wrote a class similar to the one above, and made it recognize which type of config file it was reading based on file extension (for example), and saved this class into your site_ruby/ directory, all your scripts which require cfg information start looking really short and sweet, something like : require 'cfg.rb' cfgpath = ARGV.shift cfg = Cfg.new cfgpath cfg.each do |row| ... do something end which is exactly what i've done at our site. just thought i'd point all that out since, IMHO, it's the OO aspect of ruby which is the most usefull, and yet also the aspect which requires the biggest paradigm shift. -a -- ==================================== | Ara Howard | NOAA Forecast Systems Laboratory | Information and Technology Services | Data Systems Group | R/FST 325 Broadway | Boulder, CO 80305-3328 | Email: ahoward@fsl.noaa.gov | Phone: 303-497-7238 | Fax: 303-497-7259 ====================================