http://qs321.pair.com?node_id=410951


in reply to Yet another "why CGI-Application" question

I would like to create a mix between what dragonchild calls "clannish" and "socialist" (see Re: Re: Why CGI::Application?). One directory per functional area, and within that, one script per run mode.

*sighs* I was afraid that post was going to come back and haunt me. It was mostly tongue-in-cheek, attempting to get from "The Monolithic Script" to a C::A solution in a few easy steps. Don't read too much into it.

As for answering your question(s) ... hmmm ... In no particular order:

Now, for an example. This example assumes you understand that basic concepts of OO theory. (You don't have to understand Perl OO programming - just OO theory.)

The idea is that we have three functional areas to our application.

A few further, somewhat arbitrary, requirements:

Stop and think about how you'd do this in a bunch of CGI scripts. You'd have to at least have

Now, this is no different that with C::A - you will have to have all those same functions. And, frankly, the code will be almost the same, line for line. But, there's a difference - with the CGI script method you're proposing, you will need to make sure you call all those functions in the right order in every single file. If you want to change that order, you will need to change every single CGI script. Every single one. That's a lot of work!

With C::A, you put that kind of code in one place, and only one place. Then, C::A guarantees that the code you specify will be called before the runmode. This way, by the time you get into the runmode, you know a whole bunch of stuff has already happened. For example, you know that

And, when you are done, you will also be guaranteed than any cleanup work will be done for you.

Every. Single. Time.

So, how do you get C::A to do all this magic for you? By using the power of subclassing. When I use C::A, I create a child-class, generally called Generic::Application. This is my personal C::A, modified and customized to meet my personal needs. I'll generally have 2-3 things in it:

This class will not have anything in cgiapp_prerun() or cgiapp_postrun(). This is just to provide some common functionality.

Next, I'll create Specific::Application which will be a child of Generic::Application. This will be the base class for the specific web application I'm working on. In here will be the cgiapp_prerun() and cgiapp_postrun() that will generally do things like

Each of those things may or may not be in separate methods.

Note, we haven't actually written any runmodes yet. This is all just infrastructure work - code we'll need later on down the road.

Now, remember back to our requirements - we need three areas. That sounds like we need three child classes. Specific::Application::Public, Specific::Application::Members, and Specific::Application::Admin. Each of these will also have a very basic .cgi file in the cgi-bin directory, corresponding to the last part of the classname.

Now, Specific::Application assumes that every page requires a login. We can then override that in Specific::Application::Public to say that runmodes in this class do not require a login. That's the more secure way of doing things. The admin stuff can be handled by the ::Admin class requiring that the session generated by authentication contain a certain flag set to true, indicating this is an admin user. All of this happens in the cgiapp_prerun() methods in the various classes. The same goes for cookies, databases, and the like.

Every runmode will look something like:

sub runmode { my $self = shift; my $session = $self->param( 'session' ); my $dbh = $self->param( 'dbh' ); # Do stuff here return $self->print( $template_name, $format, %parameters_to_pass_to_template_object, ); }

Everything else is handled for you. In fact, most of your developers will never need to know how things work - just that they do. Does that help?

Being right, does not endow the right to be rude; politeness costs nothing.
Being unknowing, is not the same as being stupid.
Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Replies are listed 'Best First'.
Re^2: Yet another "why CGI-Application" question
by punkish (Priest) on Nov 29, 2004 at 18:19 UTC
    Thanks much everyone. After (not-so-much) pondering, I have decided to --
    • follow a mix of Arunbear's, dragonchild's, and weierophinney's advice. I will try once more to understand a bit more of OOP, and read some of CGI-App's source (many speak highly of the framework, so there is some "capital" to be "expended," so to say).
    • Unfortunately, Damian's book will have to wait -- I have no money to buy another book -- I think I have enough in this discussion to go on forward

    dragonchild, thanks for a really detailed expounding of a really detailed expounding. I really did like your "socialist" and "clannish" nomenclature -- made more sense than other pure technical stuff (frankly, words like "class" and "inheritance" leave me cold -- esp. "polymorphism" -- that one is really frigid).

    Perl has benefited so much from its laissez-faire approach -- TMTOWTDI is a flag-bearing slogan. And that is good.

    However, I feel, Perl is used so much in web apps, and given that CGI.pm is a part of the core, maybe it would be beneficial to have something like CGI-App and H-T also a part of the core. Python-ers talk highly of Zope, and PHP-ers speak of Zend. As far as I can see, the closest thing Perl-ers have to a standardized "framework" is mod_perl, but that is such a pain in the behind to implement because it is tied to the webserver, and requires re-jigging your scripts more often than not. It might be worthwhile to have a web-application framework be a part of the language core -- compelte with all the services, session management, etc.

      (This is going wayyy off the original topic, but I follow where the conversation leads.)

      (frankly, words like "class" and "inheritance" leave me cold -- esp. "polymorphism" -- that one is really frigid)

      Words are nothing more than carriers of meaning. However, each person has their own understanding of each meaning, leading to the ideas of denotation (dictionary meaning) and connotation (personal meaning). Denotations tend to be very dry, as they're trying to pin down something that, frankly, cannot be pinned down. Connotations tend to be very emotional, like your reactions to certain words.

      Now, neither is good or bad. We use both in our daily lives to great effect. Just try to imagine a world without connotations - jokes would suck. Persuasive speech would be impossible. Politicians would ... well, maybe that's a reason for such world, but that's another discussion, preferably over several beers.

      To bring this back to your comments ... I would stop and look at the denotations of words that "leave you cold". Often, words leave me cold when I don't really understand what's going on behind them. Sometimes, I think that's why I didn't get that philosophy minor - too many words I didn't understand, so I didn't bother. Frankly, I'm indebted to this site for explaining many of the concepts behind the words of programming. Without that, I may have given up on excelling in my chosen Art.

      I would do some searching through the bowels of this site before accepting the cold shoulder from certain words. Personally, I'd look through the Meditations of the Saints. I'm particularly fond of tilly and tye, though all of them are excellent writers.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.