Mar 31

By The Grace Of Perl

Author: s1n
Category: 01100011, Project Bootstrap

I haven’t been posting anything in a while, and with good reason. I’ve been working furiously on my school work, trying to keep up as best as I can. After about a month of procrastination, my professor finally handed back our graded midterms. I was pleased to see that I had a 92, but found that he had claimed that my heuristic for one of the solutions was not admissible, even though it was exactly the same as his. We’ve been bombarded with homework as of late it seems, so I’m doing my best to complete them on time.

So the project I had to do was play a game of 9 Man’s Morris. I’ve mentioned it here before, so I’ll skip the introduction. It took me approximately 5 hours to write the initial version. That initial version was about 80% correct and very readable. It’s too bad that I have since learned that professors and TAs never read your source code, but I’ll talk about that near the end. It then took me a mere 20-ish hours to debug the program and iron out the problems that accumulated over the course of development. Since this was a largely recursive algorithm that analyzed tons of stack data, it was very difficult to distinguish good and bad behavior.

Over the course of development, I discovered (and rediscovered in some cases) why Perl is one of the most complete and challenging languages available. So I figured I’d share my refreshed love and respect for Perl.

First, the map function is the best example of simplicity. Here is an example of some code that just makes map the absolute best method for reducing simple loops down to single statements.

Crappy Original:

for(my $i = 0; i < $#array; $i++) {
   $array[$i] =~ s/search/replace/g;
   print "$array[$i]\n";
}

Better Original:

for(@array) {
   s/search/replace/g;
   print "$_\n";
}

Map Improvement:

map { s/search/replace/g; print; } @array;

It’s fairly obvious that using map is the best way to clean up that few-liner list loops (remember that @array is not restricted to a typical array, as many things can placed into list context).

Next on my list of things that I love is the prepackaged module Carp. If you love to use the die statement to help identify problematic situations, then you’ll love Carp. Carp is the bastard child of gdb backtraces and the die function. If you use the cluck function, you can cause a warning that will be accompanied with a stacktrace. When I discovered this, I was having trouble with my recursive function at only certain depths. So I tossed the following at the top of my function to check all of my parameters and optional parameters:

my ($self, $var1, $var2) = @_;
cluck "Var2 not specified" if !defined $var2;

That example was similar to how I found my problem. The example simply tosses a warning, complete with a stacktrace, when one of the variables on @_ is undefined. This is how I found out that I was never technically passing in an optional parameter to a function. Since use of optional arguments will basically leave them as undef, using them in the function with being set to undef is a valid use, just incorrect behavior. I would certainly hope there is a much better way to using optional arguments (I’m sure there is a clever module to do it).

I wanted to talk about references and tie, but I don’t think I can keep my eyes open long enough to express myself well enough. I’ll post some more this weekend as I get time.


1 Comment so far

  1. [...] By The Grace Of Perl …First, the map function is the best example of simplicity. Here is an example of some code that just makes map the absolute best method for reducing simple loops down to single statements… [...]

Leave a comment