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

When I write web applications, I tend to code in the following way: Your thoughts?
--
“Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.” M-J D

Replies are listed 'Best First'.
Re: One Big Script v. Several Small Scripts
by dragonchild (Archbishop) on Jan 28, 2003 at 22:15 UTC
    Well, the first thing is that you're compiling all the code you don't need every time you run the script. That may or may not be a big deal.

    The real issue is something else. I'm willing to bet a paycheck that you have common operations between at least three of those four modes. By breaking them out into four scripts, you find it easier to see the common modes. Then, you create a fifth "script" (called a package) that will contain this common functionality. For example, you need to validate the values to query on for editing, deleting, and listing. Breaking out common functionality is good for bugfixing and maintenance.

    Another thing is that you now have a prototypical "add" script. Let's say that you now have a second reason to use an "add" script, for some other DB or some other table or whatever. But, you don't need to re-use your delete script (yet). You can now generalize your add functionality without needing to affect the delete functionality. Maintenance is a lot easier.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: One Big Script v. Several Small Scripts
by Thelonius (Priest) on Jan 28, 2003 at 22:19 UTC
    Generally this is considered a good thing. There's even a module, CGI::Application, to help organize things this way.
Re: One Big Script v. Several Small Scripts
by jonadab (Parson) on Jan 29, 2003 at 03:17 UTC

    Others have commented on the Perl side of this, and the advantages to code maintenance of one approach or the other, but I'd like to add another consideration: the web side. It's the sort of theoretically minor thing that could easily be overlooked, but depending on your situation it could be significant.

    If you do the whole thing as one big script, all the parts of it will have the same URI; if you split it up into multiple scripts, they won't. (Another poster spoke of splitting out various modules and having the main script load those it needs; that hybrid approach could be made to fall, from the web's perspective, into the one-big-script category. Conversely, if you use GET, one script may have different URIs.)

    So you want to ask yourself, does it matter whether the various pieces have the same URI or not? If two pages have the same URI, it has a lot of effects. The browser will treat them the same for bookmarking purposes. Do you want to be able to bookmark the "add comment" page, for convenience, or do you want the user to have to go through the main page every time? Any forms they contain will probably get treated as the same page of forms by browsers that have autofill features. Is that good, or bad, in your circumstances? There may also be more subtle effects; a page that has the same URI as an earlier page may force the earlier page out of a browser's cache, for example. These sorts of things are IMO well worth considering when you decide whether to put various parts of your site in the same script or separate them.

     --jonadab

      >If two pages have the same URI, it has a lot of effects. The browser will treat them the same for bookmarking purposes.

      Actually, I tend to bookmark app.cgi?mode=edit seperately to app.cgi?mode=list and use them that way. But I'm talking about applications I write for myself alone mostly, so yes, you're right that the user-perspective is altered by the single-script method.

      Thank you all very much for your input. I feel vindicated, and also educated.
      --

      “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
      M-J D

      I suggest considering tools like the Apache module mod_rewrite to allow an indipendence of URIs from implementation choices. URIs should not change if you switch from a single script to a multiple script approach and they should be more related to contents than to application paths.

      Thus, a preliminary step should take care of converting http://www.mydomain.org/posts/insert.html to either app.cgi?mode=edit or edit.cgi.

      Cheers

      Antonio

      The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket
Re: One Big Script v. Several Small Scripts
by pg (Canon) on Jan 29, 2003 at 07:14 UTC
    The best solution goes like this:

    Better to define two objects(in Perl, actually two mudules):
    1. one object for item, has at least two methods:
      1. one method to create it from query results, not being directly called, but called by the constructor of the second class.
      2. One method to display
    2. one object for list of items (this one contains a list/array/hash (your choice) of object of the first class as its attribute), has at least four methods defined:
      1. one method to add memeber
      2. one method to delete member
      3. one method to display all member elements (which are objects of the first class). This calls the display method of the first class for each member
      4. a method to create the list from a query (after it gets the query result, then call the constructor of the first class, to form each of its member element, and also call its own add method to append each member).
      Thanks pg, that's very thoroughly laid out. I appreciate the details.

      Plus, bonus points for inventing the word "mudule".
      --

      “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
      M-J D
Re: One Big Script v. Several Small Scripts
by Gilimanjaro (Hermit) on Jan 28, 2003 at 23:02 UTC
    I just rebuilt a big script into a few small ones; there's only one CGI that's the entrance, and all 'parts' reside in sub's in separate modules, which export the sub.

    I'm currently using the 'autoload' pragma module to only load the module that's going to be used when the function gets called...

    I'm aware there's a whole bunch of other modules that can do comparable dynamic loading, but this one works for me... :)

    Addition: One that seems to be appropriate for this task is also SelfLoader which allows you to keep the code in one file, but not compile it all. In fact just adding 2 lines to working code can avoid compiling more code then you need...

Re: One Big Script v. Several Small Scripts
by graff (Chancellor) on Jan 29, 2003 at 02:11 UTC
    I would tend to modularize this sort of script at least to the extent of using subroutine calls within each of the major "mode" blocks, so that the overall scope of mode choices is presented compactly and clearly in the "main".

    Whether the mode-specific subs are stored in separate source code files may be a question of optimizing load time, or may just be a matter of stylistic preference, but in any case, the path to writing code that is minimal, optimal and easy to re-use begins with proper factoring, and factoring is mostly a matter of decomposing and organizing the program logic into functional (or methodical) blocks -- i.e. subroutines.

    (Officianados of OO would probably phrase it differently, but the overall thrust of the idea would be equivalent, I think.)

Re: One Big Script v. Several Small Scripts
by clairudjinn (Beadle) on Jan 28, 2003 at 22:58 UTC
    I think there is a balance to all this, and it may very much depend on the application. The observation about one large hunk of code being compiled even if only a little subset is used is an excellent one. On the other hand, having a bunch of files strewn around is not very portable or standalone, ie., may not be convenient. The happy medium for me is indeed the (admittedly) simplest case of a few-file system: module(s) and driver. Extracting generic functionality and modifying/calling upon it as needed in a script. You may also find the autouse pragma and the AutoSplit namespace useful in your implementations.
Re: One Big Script v. Several Small Scripts
by Mr. Muskrat (Canon) on Jan 28, 2003 at 22:18 UTC

    I've done it both ways...

    It usually depends on my mood when I'm writing. But if I see that a CGI script is getting really large, I'll split it up into smaller, more manageable pieces.

Re: One Big Script v. Several Small Scripts
by Bilbo (Pilgrim) on Jan 29, 2003 at 10:07 UTC

    I have been wondering about this recently. People in this thread have suggested that having several small scripts saves on compile time because you don't compile the whole script every time. Does anyone know if this is really significant? If you are using the CGI module I would guess that this is significantly larger than your program (it's certainly bigger than mine) so wouldn't this dominate the compilation time, or have I missed something?

       I think you're right to wonder about the benefits of this, especially if CGI.pm is involved.

       If the server is using a traditional approach to CGI's and having to do a fork() for each request the time taken for this may exclipse the perl compilation time.

       Mostly the CGI scripts I write are IO/network bound anyway - so little optimization is really possible.

      Steve
      ---
      steve.org.uk
      I really don't think having perl to compile, say, 32K file versus 8K file adds a significant overhead. Besides, as some people rightly noticed, if you use CGI one of the major overheads is having to load perl compiler on each call. So you might want to extract some common functionality of your program in a module to provide for convenience and code reuse, but you don't need to split your main script into smaller pieces. Anyone who thinks otherwise can try benchmarking different approaches.
Re: One Big Script v. Several Small Scripts
by Dr. Mu (Hermit) on Jan 30, 2003 at 03:39 UTC
    My first significant Perl script was a CGI database manager. Because it was my first script, I did a lot of things that, in the light of more experience, seem dead wrong. One of those things was combining too many functions (i.e. query handlers) into one large program. It started innocently enough. I just wanted to be able to make a query, do a search, and present the results. Then came the stats. Heck, I can compute the stats in the same program. After all, the data access engine is already there. After that came an addition to format the stats in a nice downloadable pdf. Might as well just stick that in there, too! And did I mention how convenient having all that stuff in one big script made it to use global variables? Well, you get the idea.

    As far as compile-time goes, frankly I don't care whether it's 10 milliseconds or two seconds. It's not one of those 10,000 hits-per-day sites. What I do care about is maintainability, and the capacity to modify function by building out rather than up. This could have been achieved by having one module whose only job was to interface to the database via exported data objects and methods. That way each query could have been handled by a different, much shorter script, and the data retrieved and contained in nice, tidy object variables instead of being splattered across a score or two of global scalars. Plus -- and most importantly of all -- I could follow the logic of each query handler without having to scroll back and forth through several thousand lines of code.

    Now I know. And I'm sorely tempted to do a major rewrite, except -- doggone it all -- the blasted thing works!

Re: One Big Script v. Several Small Scripts
by Wysardry (Pilgrim) on Jan 30, 2003 at 02:55 UTC

    One thing I haven't seen mentioned yet is debugging the program if there are problems.

    It should be easier to find a problem in a small document compared to a large one because you wouldn't have to scroll up and down so much to find the section you need.

    Also, some text editors (like Notepad) have a relatively small file size limit. Oh, and if an error is really hard to spot, printing out a single small script uses fewer dead trees.

    __________
    "Every program has at least one bug and can be shortened by at least one instruction -- from which, by induction, one can deduce that every program can be reduced to one instruction which doesn't work." -- (Author Unknown)