in reply to High-level methods to low-level: Do I put them together?

First, if the code works, that's all that matters ;)

Writing this out in text is very difficult for me;  a 
picture is far more useful.  Furthermore, some of my terminology
has been "personalized," so email me for an explanation of
something that you think is weird.

This post really answers your third question: "How would you do it?"

However, based on your description, it seems to me that the
program does not have any sort of generic definition of a 
log.  You have a series of log types, but no generic log.  In
this model, a log shall simply be an aggregation of data 
elements of differing data types ( build a log from components 
that any log may have ).  Right now you have specific logs
with specific components.  Do any of these components overlap?

Each log will be of its own type.  This means that your 
program will be asking questions of the logs by log type.  

Example:   You have a 5 log instances bunched together in 
the queue.  Your base class is called Logger.

At the correct time, Logger asks:  Who is an http log?
2 logs raise their hands.  Logger hands them off to 
Lumberjack_1 and forgets about them.  

Logger then asks:  Who is a wombat log?  3 logs raise their
hands and they get routed to Lumberjack_2 and forgets 
about them.  

The Lumberjack_X methods could be in the base class or 
in Log_types, depending on what you want to do.  I would put
them in the base class Logger.

In each case, Logger is asking a question of the log.  Once
an answer is received, an action occurs.

The basic definition of the log will be in your base class.
All elements common to all logs live here.  Furthermore,
the base class will contain all common methods.  

All deltas will be in derived classes, as you well know.
The idea here is that Logger does not know about the different
types of logs.  In order to get that info, it has to get
it from Log_types.  Log_types doesn't know much about
log components, so it defers to the to wombat
or http to get the correct object with the correct data.

The key is to defer from generic to specific.

The notion of virtual base class will probably help out
here.  In this case, base class Logger will have a virtual
base class called Log_types.  Underneath Log_types will
be the various types of logs:  Http and Wombat.

But what does Logger have besides Log_types?  It also
has a Report_interface.  Report_ifc could then have
Gui_ifc and Text_ifc.  Report_ifc would be another
virtual base class.

The 'Has-a' relationship between Logger and Log_types
for making an instance can look something like this:

Option 1:

in your base class:

$log -> make_log( 'wombat' ); # wombat is-a type of log

in your derived class:

my ( $log, $log_class_name ) = @_;
my $message = $log_class_name -> new(); # run the correct new()
$log -> logs( $message );  # this is Has-a in action
return $log;

Notice how the instance, $message, is placed within the 
context of $log. 


Option 2:

in your base class:

$log -> add_log( 'wombat_log', 'log_details' );

in your derived class:

my ( $log, $log_name, $log_data ) = @_; 
my $message = $log -> logs() # this gets data AND renames
# the instance

$message -> add( $log_name, $log_data ); # adds data to instance by
# going to the correct 'add' method

return $log; 


Programming Perl has a small section on 'Has-a' on page 318.

When you are building this, just get it to work for one
simple log ( like the HTTP log or something ).  

I hope this helps.

--moo
  • Comment on Re: High-level methods to low-level: Do I put them together?

Replies are listed 'Best First'.
RE: Re: High-level methods to low-level: Do I put them together?
by jeorgen (Pilgrim) on Jul 17, 2000 at 03:09 UTC
    Thanks moo for the thinking about the log analyser code. I develop it for a customer that agreed to make it Open Source so it is available at sourceforge, with some docs too on what the objects do. The name of the analyser is a bit weird, because I didn't want to put it any of the CPAN namespaces. It's in beta, with a lot of out of date comments and other weird stuff; it's probably not of any use for others yet.

    Regarding making the log analyser general, I only intended it for web server logs, however it is built to make statistics of any log file. The only assumption about what kind of log it should parse is that it should consist of lines (Monday correction: it assumes there is a date pattern too of a particular format). The line assumption could easily be taken away by changing the LogFile object. Categories are defined as a pattern and a title for the category, so you should be able to match anyting that is, er, matchable. You can also put in some code for each category (e.g. the Query module unescapes the query string, before storing statistics). Next step will be to put in a slot for a private data structure that can be used by an object to have a memory between lines, for recording sessions.

    A lot of other stuff is hard coded, e.g. HTML.

    /jeorgen