Thanks to all who gave advice about the best way to get matching regexp
items out; I found it very helpful. After years of doing most of my OO work
in Java, it's exciting to be reminded that an OO language can be as
programmer-friendly as Perl.
Here's the next thing that I'm puzzled about. I'm looking for the most
efficient way to do a Factory pattern.
When parsing a system log file, there are lots of lines of different sorts.
It would make sense that one should have a base class, LogLine, and then a
bunch of subclasses for particular entries (SendmailLogLine, NamedLogLine,
etc.).
So one might start out with
class LogLine
attr_reader :month, :day, :hour, :minute, :second,
:host, :program, :pid, :message
[...]
end
But from there, I have two questions:
1) Is it possible (or even sensible) to override LogLine.new so that it
returns an instance of the appropriate subclass? I've never liked the
Java-style LogLine.getInstance(args); it seems unfair to make programmers
keep track of whether you're using a Factory internally or not.
2) What's the most efficient way to give each subclass a chance to say "Yes,
that line is best represented by me," without doing a lot of repetitive
parsing?
The obvious OO way seems to be that each subclass would, on loading,
register itself with LogLine. As each new LogLine is created, the
superclass would show the line to each of the subclasses, and whichever
subclass liked it the best would be instantiated with the data from the
line.
Done naively, this would mean that each subclass would parse the line, but
that would be wasteful. So obviously, the superclass should do the basic
parsing once and pass the details down. Passing as an Array is brittle and
not very OO. Passing as a Hash is better, but still not right.
Really, the parsed data is best represented as a LogLine, no? So it would
make sense to instantiate a LogLine with the base data, and then pass that
to the subclasses. But when instantiating the subclass, the subclass has to
copy over all the data and throw out the copy of the superclass, which
seems a little wasteful.
So is it possible for a subclass to somehow replace an instance of its
superclass with one of its own, stealing its data without explicitly
copying each field?
I suspect the answer to this is "no", but Ruby's OO is so much more flexible
than what I'm used to that I thought it would be good to ask.
Many thanks,
William