From: James B Crigler Date: 2004-10-05T23:34:55+09:00 Subject: Table-driven dispatch I need to read a file into memory and parse it for information on demand as a kind of ad hoc query mechanism. (The file is a non-tabular report from a database.) Though there are other field types, for the time being, I only want to consider fields that appear with a tag on a single line, e.g., Title: A Tale Of Two Cities Author: Charles Dickens There are various classes of files representing different object types as reported from the database. The tags, even for fields like title and author, are not consistent among report types. (I don't have control of the database, so I can't fix it.) My original implementation approximated the code you'll find below. There are some annoyances in the code: 1. The deferred lookups have to be written individually (def title, def author, etc.), though they only have to be written once if they belong in the base class. 2. I pass the variable into find_tagged_one_line to see whether it already has a value, but I can't assign it there. Is there a way, e.g., with missing_method, to create a table-driven caching dispatch on the field names that performs assignment in the find_... method? class Literature Tags = { 'title' => %r[^Title:\s*], 'author' => %r[^Author:\s*], # etc } def initialize(path) @text = Array.new @tags = Tags @title = nil @author = nil if File.exists? path File.open(path).each do |line| @text.push line.chomp end # else # raise NoSuchLiterature end end def find_tagged_one_line(re, var) return var unless var.nil? # Got a value? Return it m = nil line = @text.find { |l| m = re.match(l) } # Match RE in array of lines return "" if line.nil? # No match? return line[m.end(0) .. -1] # Return part of line after tag end def title @title = find_tagged_one_line(@tags['title'], @title) end def author @author = find_tagged_one_line(@tags['author'], @author) end # etc end class Novel < Literature Tags = { 'title' => %r[^Novel Title:\s*], 'author' => %r[^Novel Author:\s*], 'year' => %r[^Year of publication:\s*], # etc } def initialize(path) super(path) @year = nil @tags = Tags # Override the tags hash end def year @year = find_tagged_one_line(@tags['year'], @year) end end -- James B Crigler Voice: (770)494-2077 C-27J Software Requirements Manager Fax: (770)494-3886 Lockheed Martin Aeronautics Company D/6B3M Z/0100 86 South Cobb Drive Marietta GA 30063 "I say, Jerry! You'd be in a Blazing bad way if recalling to life was to become the fashion, Jerry!" -- A Tale of Two Cities