I don't inherit because there isn't really a parent-child relationship between the different modules. I'll explain in detail what I'm doing in my current project. It's done this way not because I designed it this way from scratch, but because I'm refactoring existing functionality from a mess of spagetti-code and using CGI::Application modules to split it up into managable pieces seemed like a good way to go.

Say I have 3 main pieces of code for a shopping cart - user management, product management, and order management. In this case, I'd have one CGI::Application module that works on the run mode "action" variable. So we'd have three run-modes: user, product, and order.

My "Main" CGI::Application would be using the "action" variable to decide the run-mode. It's only choices would be user, product, and order. Depending on which of these it is, it would instantiate another CGI::Application module of that type. So if the main run-mode is "user," it would do something like:

my $user_app = new UserApp(...);

The nice thing is that since each run-mode in "Main" is related to a different thing (user, product, or order), I can use those run-modes to set up the environment for each of those sub-run-modes differently. For example, if I have a "user" class which is used to do database interaction with the users table, I can create a user object and pass it to the User CGI::Application module as a parameter. That user object won't be created for the other modes if they don't need it.

I should probably post some code, I'll try to write it as I do it, but this is untested:

use strict; use warnings; package MainApp; sub setup { my $self = shift; $self->tmpl_path('./templates/'); $self->mode_param('action'); $self->run_modes( product => 'product', order => 'order', user => 'user' ); } sub product { my $self = shift; use Product; use ProductApp; my $p = new Product(); # Say this is an object with methods to int +eract with the products database my $pa = new ProductApp( PARAMS => { p => $p } # more args... ); return $pa->run(); } sub order { # Similar to product() } sub user { # Similar to product() } package ProductApp; sub setup { my $self = shift; $self->tmpl_path('./templates/'); $self->mode_param('task'); $self->run_modes( add => 'add', edit => 'edit', delete => 'delete' ); } sub delete { my $self = shift; my $cgi = $self->query(); my $p = $self->param('p'); if($p->delete($cgi->param('product_id'))) { return "The product was deleted!"; } else { return "There was a huge error."; } } 1;
The thing to notice is that the sub-modules work off a different run-mode name ("task" vs. "action"), so if I wanted to grab that delete method, I could go like this:

http://some-url/?action=product&task=delete

And of course to actually get it to delete something you'd have to pass a product ID:

http://some-url/?action=product&task=delete&product_id=1234

The reason I have different classes/objects to do database interaction is because we do a lot of reports and processing with command-line scripts in addition to our CGI::Application modules. If they're abstracted out like that, we can use those interfaces to do stuff from command line scripts as well without having to rewrite the same DB queries in multiple places.

Anyway, I know this doesn't really address your question about inheritance, but I, like other people here, really don't like to use inheritance unless there is really a parent-child relationship. Generally, at least for me, there isn't such a relationshiop among various CGI::Application modules, as those don't contain much "real" logic - they are just interfaces to the real DB work that goes behind the scenes.

In reply to Re^3: CGI::Application, inheritance trees, and 'the right way' by saberworks
in thread CGI::Application, inheritance trees, and 'the right way' by geektron

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.