Randal Schwartz's Perls of Wisdom
Perls of Wisdom is a collection of 65 selected columns from Linux Magazine, Unix Review, and the now-defunct Web Techniques magazines, written between May 1995 and July 2004. In each column, Randal discusses some problem that he had to solve, or that someone else needed help in solving. He carefully discusses the problem, and then shows the Perl code needed to resolve it. Many of the columns are complete applications that can be run (with minor modifications) by the reader. (The listings are also available from the apress.com web site.) Each column has been reproduced as it was written in the original magazine, with "Randal's Note" prepended. Therein lies this book's best feature and greatest flaw. Allow me to explain.
When I first picked up this book, I had only read a couple of Randal's columns (from Web Techniques), and saw that he wrote tutorials of proper Perl usage. He also relies on the wealth of modules submitted to CPAN to leverage a solution. After all, why reinvent the wheel? I expected to see more commentary on the reasons behind choosing one solution over another, or insights into the inner workings of Perl itself. I more or less got what I expected. For example, the first column reproduced in the book (It's All About Context) explains why, when someone used my ($f) = 'fortune'; instead of my $f = 'fortune'; he got in trouble with the law (see the book to understand the legal issue). The first form only retrieves the first line of the output of the fortune program, while the second form retrieves the entire output. Little items such as scalar versus list context can trip many Perl coders.
The first chapter (Advanced Perl Techniques) does give you many tips and insights like the example I just gave. All but two of the twenty columns are little tutorials on the ins and outs of handling the commonplace day-to-day issues that Perl can address with ease. Some delve into more obscure topics, such as the difference between shallow and deep copies of structures, and Perl's Taint mode. Two columns contain complete programs. One extracts the text from the man pages and determines their "fog" index (a measure of readability). The other creates a mirror of files needed by CPAN.pm to install new modules. For each program, Randal gives the entire listing as well as an almost line-by-line description of how it works. Each column is written in a conversational style that is easy to read, yet doesn't talk down to you.
The following chapter is comprised of seven tutorials on the various aspects of searching, sorting, and formatting text. In addition to describing the creation and compilation of regular expressions, Randal also discusses formatting and the nifty "Schwartzian Transform" (Perl's map-sort-map idiom for sorting on almost anything) which was named for him, but not by him. While some of the information is a little long-in-the-tooth (the column on Text-Processing was written shortly after Perl 5 was released), it's all interesting and educational nonetheless.
Chapter 3 starts refocusing the use of Perl to web sites. This chapter discusses HTML and XML processing in six little columns. He shows how to generate a web page index, producing a web page calendar from a file of events, and parsing XML to retrieve the data within. He also includes a lesson on how to use Perl to compare two arrays to create an HTML-formatted difference table.
The next chapter demonstrates that Randal has spent a lot of time working out ways to update and improve his web site. It covers the intricacies of CGI programming in Perl. All but one of the fifteen columns are complete programs (again, available from apress.com) with line-by-line commentary. The programs do implement mostly worthwhile functionality, but each column was pretty much "I had this problem, so I wrote this program. Lines 1-3 do this; lines 4-5 do that, etc." Granted, some of the programs are pretty nifty (check out how he automatically keeps track of the "What's New?" pages), but the reading of one program after another started to become stale.
The final chapter is titled "The Webmaster's Toolkit," consisting of fourteen programs and three tutorials. Randal covers diverse web server background topics such as creating a light-weight load balancer, random links, and forcing users to enter through the "front door." There are also instructive techniques for throttling your web server's usage of the processor (a necessity at the time for Randal, as his web site was co-resident on a server with others), and calculating download times.
In its entirety, Perls of Wisdom contains 65 columns, split roughly half-and-half between tutorials and fully commented programs. More than half of the columns show that Randal uses Perl for web processing more than for general scripting, data reduction and reporting. His tutorial articles are top-notch, but I have a quibble over his program articles, which are somewhat dated. There were a number of prefaced notes to the effect that today he'd do it differently with some new feature or CPAN module. I really wish he had actually updated the column to show the new coding techniques. The original code is interesting in the historical sense, but I wanted to see nuggets of Perl wisdom for me to use in my daily job. The writing style is fine; the bits of insight are useful, but many of the programs are too specific to problems you or I may never see, and were solved in code that's showing its age. I'm glad I got to read the book, but I think it only rates a 7 out of 10.
You can purchase Randal Schwartz's Perls of Wisdom from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
Because of Perl's TIMTOWTDI mantra reading other people's code can be an exercise in frustration, IMHO, because to grok what they have written you may end up delving into some of the more baroque syntax in the language. I've found that many people like writing incredibly terse code which makes its readibility incredibly difficult. While Schwartz may write comprehensible Perl, I expect that the bulk of Perl code in the wild is anything but. This is my biggest peave with the language, and how it can pride itself on this "feature" is beyond me.
People kill readability (with Perl).
Seriously, choose the right tool for the job. When we've got a sys-admin level scripting task, and someone can go in and knock it out in a half hour (or less) with a few lines of Perl, who can say that's bad? I'm currently wading through a bunch of heavily patternized java that pulls checkin logs from a scm system and updates an issue tracking system as part of the build process. It's taken me *days* to begin to "grok" what's going on in the many associated xml config files and bizarre string handling approaches that were used in this undocumented hack. I'll replace it with probably less than 150 lines of Perl, and someone else will happily (and much more easily) maintain it. So there!
At the same time, we've got > 25 developers distributed around the world working on a big commodities trading app -- java works pretty well for that.
who's moderating the meta-moderators?
It is not how long it takes you to understand a perl script of X length that is relevant.
What SHOULD be the important data is: Whether it would take you MORE time to understand a C or Java program that does the same thing.
I have seen cases where people complain that it takes them a week to understand a Perl Script of 500 lines. So they write a new program in C, that does the same thing in 5,000 lines. Which then takes me 8 days to understand.
One of Perl's image problems is that because it does so much with so little, people underestimate what the tiny program does and therefore get frustrated when it takes them more time to understand than a C program of the same size, even though the C program does 1/10 what the Perl one does.
excitingthingstodo.blogspot.com
that's part of the problem with perl -- the code is often incredibly terse and dense.
:-P
you can do incredibly complex things in a few characters in perl, which can be far more difficult to grok than the same thing described in 20 lines of C code.
it's both a blessing and a curse. a blessing because you can beat out very complex things quickly, and a curse because it is a major pita to maintain.
perl also stubbornly avoids some useful language constructs in the name of "language purity". eg case statements. yes i know about Case.pm, but its not stock perl. and yes i know perl6 will have it. only took them ~20 years to get there
It still takes more effort for me compared to python. Not compared to C, but C takes lots of instructions to do simple things - use only when necessary. And I think the problem is that the syntax is so different. You throw a c/java/python/etc. program at a programmer from another language and they'll get the basic idea. They'll be able to see where the functions are, how the control flow goes, with a little bit of effort what the variables are. You throw a perl script at someone who hasn't seen perl, and a few are alright, but most look like so much line noise. You have to relearn a lot of your programming knowledge, and if perl isn't your only language then you have to switch modes when you see it. If I could program with it all the time, it would be good, but the fact is I have to use C and Java a lot of the time, so I need a language which isn't too different from them.
I am trolling
its the developer that writes unmaintainable code.
TMTOWTDI and the Perl syntax have hardly anything to do with badly written code in Perl or any other language. Sure understanding an expressive language like Perl takes a bit more than learning a language like Java. But that does not mean that Java or [insert any language here] prevents you from writing ugly code. I am primarily working as a Java developer on mostly large projects and the amount of badly written code I have to deal with is simply frustrating. And most of it is written by "Senior" developers and design pattern aficionados!!!
Perl Programmer for hire
It's not difficult to read at all; however, you wrote it in backward perl syntax with implicit variables. It's easy. It prints a concatenated list of prime numbers between 2 and 100 with no delimiter.
So, let's rewrite this program without implicit $_ variable, without && comparision and with a temporary variable.
for my $number (2..100)
{
my $unary_string = (1 x $number);
if ( $unary_string !~ m/^(11+)\1+$/ )
{
print $number;
}
}
Which is quite readable now.
For all numbers between 2 and 100. Take that number convert it into UNARY format. Now, if it doesn't match recursively the first set of ones (at least 2) with the trailling set of ones having the same number of ones (at least once).
So basically the matching algorithm is like this:
2 11 insufficient
3 111 insufficient
4 11 11 matched 4
5 11 1 11 mismatch
6 111 111 matched 6
7 111 1 111 mismatch
8 1111 1111 matched 8
9 111 111 111 matched 9
10 11111 11111 matched 10
11 11111 1 11111 mismatch
It seems to test for prime numbers...
If it's not a non-prime number since no match is found it prints the number without any delimiter on stdout.
Conclusion:
If I was to write this script with this "algorithm", I would write it like this:
#!/usr/bin/perl -w
# Print prime numbers between 2 and 100 by converting it into unary format and by testing for matching multiple pairs of double ones or more.
for (2..100)
{
my $unary_string = (1 x $_);
print if ( $unary_string !~ m/^(11+)\1+$/ );
}
BTW, writing a program in C to test for prime number would be quite more complicated!
Especially if you use this algorithm without a regexp library!
Enjoy!
Fred.
- Long life to Perl!
Unlike some other programming languages, Perl has no offical switch or case statement. That's because Perl doesn't need one, having many ways to the same thing. A bare block is particularly convenient for doing case structures. Here's one After this, there are four other examples showing this in more ways. Go get the Camel, it's invaluable.
Bran muffins and whiskey.
I wrote a Perl script yesterday with a bad algorithm using 2 lists. Ran all night and was still running when I got into the office this morning, and it didn't spit out any relevant data.
Rewrote the script using 2 hashes in about 15 minutes. Completed in less than a minute with all the info I was looking for.
So, um, I think an evaluation of most programming languages is more dependant on the programmers than the language itself. Sure some languages lack the proper data types or features, but any modern/complete language is capable of being readable and resource efficient if the programmer knows what they are doing. IMO, of course. I'm not a developer.