Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^2: CGI::Application, inheritance trees, and 'the right way'

by Joost (Canon)
on Nov 01, 2004 at 23:35 UTC ( [id://404464]=note: print w/replies, xml ) Need Help??


in reply to Re: CGI::Application, inheritance trees, and 'the right way'
in thread CGI::Application, inheritance trees, and 'the right way'

If you do inherit both child-applications from the "main" application, do you instantiate the base first and then re-bless, or create a new child object when needed?

Or do you do something else entirely and have I misread your post?

Just curious

  • Comment on Re^2: CGI::Application, inheritance trees, and 'the right way'

Replies are listed 'Best First'.
Re^3: CGI::Application, inheritance trees, and 'the right way'
by saberworks (Curate) on Nov 02, 2004 at 00:20 UTC
    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.
      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(...);

      You might want to take a look at CGI::Application::Dispatch. It does the same sort of thing in that it uses the URL to figure out the application & runmode. So the url "/app/product/delete?product_id=1234" would map to the YourPrefix::Product CGI::Application class (the prefix is configurable) and set the runmode for said application to "delete". It seems like the same as idea as your code above, but with less code you have to write. :-)
      this is the direction i was thinking, because the inheritance probably isn't the best way to be doing this.

      i assume you posted some pseudo-code, but really, the  use statements should be closer to the head of the module ...

        Actually you can put them anywhere, but you're probably right they should be put at the top since they're included at compile-time anyway.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://404464]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-20 04:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found