Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

(Ovid) Re: A question about the best way to use subroutines

by Ovid (Cardinal)
on Mar 25, 2001 at 15:43 UTC ( #67011=note: print w/replies, xml ) Need Help??

in reply to A question about the best way to use subroutines

I love questions like this. So many people focus on the "how do I do X" instead of the "why do I do X". Trying to figure out the "why" has been a subject of interest to me lately and I enjoy reading the responses when these issues pop up.

A couple of simple answers (with liberal amounts of self-promotion): in this node, I was comparing and contrasting two different approaches to the same programming problem. The one that I listed on the top was how I prefer to code. The example I listed underneath was how the code often comes out. If you read through them carefully, you'll see that the difference stems, primarily, from how subroutines are used.

Generally, every subroutine should do pretty much one thing and do it well. If you have a subroutine that validates someone's username/password combination, it shouldn't also be going out and grabbing the lastest CNN headlines. Some routines, though, need to do other things. I treat them as "traffic police." I have them do as little as possible except figure out where the rest of the program is going. As a result, everything pretty much gets broken down into a series of successively smaller functions with appropriate names. Here's the main snippet from one of my programs:

#!C:/perl/bin/perl.exe -w use strict; use URI::Escape; use HTML::Entities; use CGI::Pretty qw/:no_debug/; $CGI::Pretty::INDENT = "\t"; my $q = CGI->new; my $table_data = create_table_data(); my $source_code = read_source_code(); create_web_page( headers => [ 'Symbol', 'ASCII Value', 'URL encoded', +'HTML code' ], data => $table_data, code => $source_code ); exit;
Note: You can find the entire program at the bottom of this page, if you're really curious.

If you wanted, you could go down into each of the subs and figure out exactly what they do, but from just these few lines, you already have a decent idea of what the program is doing. Further, since the subroutine names are descriptive, this allows me to exclude a lot of extraneous documentation.

I think the "documentation" point is underappreciated. I'm sure you've read before about the perils of overdocumenting:

# add $y to $x $x += $y; # If $x is greater than three, give them some output, # otherwise, we die if ( $x > 3 ) { give_them_some_output( $x ); } else { die "This is a stupid program."; }
I think virtually everyone appreciates the stupidity of the above comments. If comments are needed there, they should be telling why we die if $x <= 3. However, if we have broken our program down into a successively smaller series of subroutines, and if those subroutines are appropriately named, once again the documentation issue becomes less significant:
&initialize_global_variables; create_debugging_log( $debug_file_location ); grant_editor_priveleges( $user ) if $user eq "Admin";
You may not know what any of the above subs do, but you probably have a pretty good idea. Further, if you know what the output of the program is like, having things broken down like that is a gift from the powers that be.


Update: Another three points I should have made:

  1. Code that is broken down into small, modular chunks (via subroutines) is much easier to maintain as you will have fewer side-effects with each section. Do you know its inputs and outputs? That's all you really need to know fix that section of code. By not breaking things down to that level, it's much tougher to determine the scope of your changes.
  2. Back to documention: documentation can be problematic because you have to maintain two things: the code and the docs. Very often, a programmer will update the code but "forget" the documentation. Because code broken down to a bunch of sub calls tends to be more self-documenting, the actual documentation can be reduced to "why" the program is doing stuff as opposed to "how". Since the "why" changes less frequently, there is less chance that the documentation gets out of sync.
  3. Last point: have you ever noticed how long-winded that Ovid guy gets when he has time on his hands?

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://67011]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (13)
As of 2017-11-22 20:55 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (327 votes). Check out past polls.