Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

CGI coding style

by 2501 (Pilgrim)
on Dec 09, 2000 at 00:22 UTC ( [id://45785]=perlquestion: print w/replies, xml ) Need Help??

2501 has asked for the wisdom of the Perl Monks concerning the following question:

I have a large CGI script which acts as a navigation point for traversing other pages and scripts.
The main portion of the script is the mother of if-then-else nests.
It works perfectly, but it is a nightmare to maintain. It also isn't very modular. Every so often it requires a rewrite to clean up and condense the nest.
ideally, it would have been great to use a hash like:
%PageIWasAt = ( 'start' => \&runfirstscript, 'runfirstscript' => \&runsecondscript );
unfortunately, sometimes I would also need to handle a couple of lines of code in an if-state, or set some variables before determing the next step in the CGI to take.
I was wondering how other monks handle this sort of thing in a more modular fashion, but with a little more flexibility then a hash would offer.

thanks for your time!

Replies are listed 'Best First'.
(jeffa) Re: CGI coding style
by jeffa (Bishop) on Dec 09, 2000 at 00:52 UTC
    Well, this might be going out on a limb, but . . .
    Sounds like a job for polymorphism!!!

    Here's the scenario - you have a group of objects, each derive from a common parent (default). Each objects overrides a method called handle - which will take care of the task at hand.

    Here is code for the Default class:

    package Default; use strict; sub new { my $class = shift; my $self = { }; return bless $self, $class; } sub handle { my ($class, $text) = @_; return $text; } 1;
    All it does is contain an empty hash, and a method called handle which simply returns what it was handed.
    Here are two classes that will derive from Default:
    package Upper; use strict; use Default; use vars qw(@ISA); @ISA = qw(Default); sub handle { my ($class, $text) = @_; return uc($text); } 1; ################################ package Lower; use strict; use Default; use vars qw(@ISA); @ISA = qw(Default); sub handle { my ($class, $text) = @_; return lc($text); } 1;
    And finally, the test script. It is a very simple and generic test to show the flexibility in using polymorphism.
    #!/usr/bin/perl -w use strict; use Default; use Upper; use Lower; my $arg = shift || ''; my %handlers = ( default => Default->new, upper => Upper->new, lower => Lower->new, ); my $ref = $handlers{$arg} || $handlers{'default'}; print $ref->handle("AaAaAaAa"), "\n";
    The hash is used to map command line arguments to the class to use - your problem might map the name of a web page to the class to use. If the argument is not including among the handlers, then the default handler is used. This will allow you to make new handlers (which print out the appropriate HTML page).

    If you want to try this out, put each of the 3 classes in their own file (with .pm extension), and copy the test script to an executable file in the same directory. Run the test script with

    • no args
    • the arg 'lower'
    • the arg 'upper'
    • the arg 'foobar'
    Hope this helps, at least I hope it gives you insight into ways to solve your problem.

    Jeff

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)
    
Re: CGI coding style
by AgentM (Curate) on Dec 09, 2000 at 00:53 UTC
    Believe it or not, princepawn has a nice list of CGI "simplifiers" (as I like to call them). I can strongly recommend CGI::Application but I also know that HTML::Mason is very popular. The use of HTML::Template can very quickly and cleanly clean up your Perl script. Give 'em all a try, some work in combination for ultra-sleek Perl scripts- especially if you're doing DB stuff.
    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.
Re: CGI coding style
by Maclir (Curate) on Dec 11, 2000 at 03:01 UTC
    While this may not be directly applicable to your situation, you may want to try some sort of "finite state machine". (Purists may say this is not a true fsm . . . )
    $state = 'initial_state'; while ($state ne 'completed') { if ($state eq 'state1') { #do something $nextstate = 'another state'; } if ($state eq 'state2') { # and so on } $state = $nextstate; # so we don't confuse our logic }
    Sure, it is not oo in style, but it can be easier to maintain.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2024-04-25 22:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found