Paradigms for CGI application development?

Michael Stillwell mjs at beebo.org
Tue Nov 5 07:09:22 CST 2002


Good CGI discussion this week!

I've been thinking recently about some of the more crapful aspects of 
CGI application development.  In particular, what techniques to people 
use to get around the fact that CGI applications don't get the 
(surprisingly helpful) implicit preconditions and automatic stack and 
scope maintenance bits and pieces that regular applications get for 
free (simply by ordering and nesting statements)?

For example, in a regular application, to get the user to confirm the 
transfer of some amount of money from one account to another is a 
matter of a few lines of code like:

   if (confirm(sprintf("Really transfer %d dollars from %s to %s?", $n, 
$a1, $a2))) {
     # DO TRANSFER
     message("Transfer successful");
   }

   else {
     # ABORT TRANSFER
     message("Transfer aborted");
   }

To get the equivalent effect in a CGI application (where the "confirm" 
screen appears on a separate page) you need to do an amazing number of 
things yourself:

1. Because Perl doesn't make it very convenient to jump (or transfer 
control) to the *middle* of a function (actually, I'm not sure that 
this is even possible), you need to break your functions in two 
whenever you seek user input.  So in the example above, the code 
following the call to confirm()  must appear in a separate function.  
Another shitty consequence of this is that you must supply the "return 
address" to confirm() yourself:

   sub transfer_part1 {
     # ...
     confirm("Really transfer?", "transfer_part2");
   }

   sub transfer_part2 {
     my ($result) = @_;

     if ($result) {
       # DO TRANSFER
     }

     else {
       # ABORT TRANSFER
     }
   }

2. You need to save and restore state information, so that when you 
return from the confirm "call" (in transfer_part2()) you know what $n, 
$a1 and $a2 were, as well as what the account number was, etc.  (And, 
you can't use any sort of conventional stack for this because you have 
almost no control over the route the user takes through your program.  
For example, you can't even guarantee that confirm() will return before 
something happens elsewhere in your program, because the user backed up 
a few pages and hit submit.)

3. You need to confirm, in transfer_part2() that the user really is who 
they say they are.

How do people get around these problems?  Why is the code for web app 
UIs very different to that of desktop app UIs?  I suppose some of these 
problems could be solved if the web server kept the running program in 
memory across requests (instead of starting a new instance each time), 
but I don't know of any system that does this.  Are there any?  (And I 
haven't thought about it much, but I suspect this approach would also 
be horribly complicated too, albeit in different ways.)





--M.

* * *
http://beebo.org




More information about the Melbourne-pm mailing list