This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

August 05, 2010

The Nature of Exceptions

While I was at YAPC::NA this year, I got a chance to catch up with a few old friends and talk with some really knowledgeable people from other parts of the Perl community. One such discussion started when Rob Kinyon told me that "exceptions are fundamentally flawed by design and should never be used." (I'm paraphrasing here. I didn't take notes on his exact words.)

I've used exceptions in multiple languages in the past decade. I've seen both good and bad usages of exceptions. I've also heard many of the arguments against exceptions over the years. (I actually touched on these years ago in the post Joel on Exceptions.) I asked if he could explain, mostly so I could hear which arguments he would use. I really expected the same old arguments. I was quite pleasantly surprised when Rob made some really interesting points in a direction I had not heard before.

If I understood him correctly, there were two major points to his argument.

  • Exceptions thrown by functions down the call stack and caught later introduces coupling between widely separated pieces of code.
  • The exception object is not part of the parameters or return of any of the functions, so it acts somewhat like a global variable, which is bad.

These arguments were not like the normal complaints I've heard about exceptions. Rob's arguments were actually fairly well-thought-out and well-argued. During the discussion, we ended up attracting Piers Cawley into the discussion. The discussion turned pretty lively after that.

Coupling

I don't think I presented my thoughts very well in that discussion. So, here goes. Let's start with the coupling argument. The simple example of Rob's argument looks something like this (in pseudo-code).


sub foo {
...
bar();
...
}
sub bar {
...
baz();
...
}
sub baz {
...
if( bad_stuff ) throw bad( "Shouldn't do this." );
...
}

Rob suggested that foo() is now coupled to baz() because it needs to be aware that a bad exception may be thrown. This would obviously be bad, because baz() is an implementation detail of bar() and foo() should only know about bar().

In fact, foo() is not coupled to baz() at all. Calling baz() has just expanded the interface of bar() to include the ability to throw a bad exception. In fact, that is no different than if the implementation of bar() were changed to throw a bad exception. This is really no different than having to change the calling signature of bar() to add a new parameter needed by baz(). The foo() function does not need to know what bar() does with the parameter (or exception), just that it is part of bar()'s interface.

What this argument does point out, however, is that the exceptions that may be thrown by a function are a hidden portion of the interface. Now, I'm sure some Java-fans will be getting smug about Java's checked exception system. Using this facility, the programmer must specify all of the exceptions that may be thrown by a method. Unfortunately, it's been my experience that system breaks down in maintenance as changes in lower-level code necessitate touching arbitrary amounts of calling code to fix up the throws clauses to deal with new exceptions.

It seems that many programmers eventually either change to unchecked exceptions or declare that all methods can throw an Exception or Throwable, so that anything is allowed. Better design skills or an architecture that converts exceptions to more generic forms as they move between layers can mitigate this issue. But, it does point out an implementation issue with exceptions. Exceptions seem to either result in a hidden interface or a lot of extra maintenance. Perhaps later implementations or better architectures will remove this issue.

Exceptions as Globals

The other argument that Rob made was that exceptions are basically global objects. Like globals, when you access the exception object you have little idea where in the code it was generated. Possibly the biggest problem with a real global is that it may be changed by literally any piece of code in the system. The only way to find out where the global is modified is to examine every piece of code in the system.

Rob's argument was that it is possible that you would need to examine a large amount of code to determine the context for the thrown exception, since the exception might have been thrown from a point far from where we catch it. Unlike a real global, exceptions are only created in code called by the point where we catch the exception. So, in theory, this limits the amount of code that would need to be examined. In some cases, however, this limited amount of code could still be a large section of the codebase.

Java exceptions reduce the effects of this issue to some extent by providing a stack dump in the exception. Depending on the system, that might be almost as bad as searching the code. Other systems support a method of chaining exceptions. In these kinds of systems, you catch an exception when you have more context to add and throw a new exception containing the old exception and further context information. Done correctly, this can reduce the noise of a stack dump type exception and increase the real, useful context available to deal with an exception.

The Meaning of an Exception

One of Rob's arguments was exceptions are not actually necessary. He argued that when something goes wrong in code, there are basically two possible ways of handling the problem.

  1. Automatically recover the error condition near the point of the problem.
  2. Code gives up and hands control to a human to handle it.

Piers made the very useful observation that exceptions give us another recovery method in between those. This allows the code to basically say I've got a problem I can't handle, someone handle this for me. If no code handles the exception, it basically degenerates to the second case. But, if higher-level code has more context and can actually handle an issue that the low-level code can not handle, an exception allows the code to turn the second case into the first.

So an exception can actually be looked as a a call for help from the lower-level code for someone else to deal with a problem.

Conclusion

To me, at least, Rob's arguments were interesting, but not compelling reasons to avoid exceptions. They also weren't strong enough to justify the claim that th design of exceptions are fundamentally and fatally flawed. I would also agree that certain implementations are less than ideal and that the best exception implementations only exist in the future.

Posted by GWade at 07:10 PM. Email comments

June 25, 2010

Open Source and Volunteer Organizations

I just got back from YAPC::NA 2010. As usual, the presentations were great and the people were better.

At last year's YAPC, I had the good fortune to attend a talk by Karen Pauley entitled Remote Controlled Volunteers. It's not the kind of talk I would normally look for, but I thought I would check it out anyway.

Boy, was I glad I did. Karen (currently The Perl Foundation president) has a lot of experience dealing with volunteers. Her observations of the connections between the open source community and difference kinds of volunteer organizations were right on target. Since my wife does a lot of work with volunteer organizations, I wanted to show her Karen's slides. I was never able to find them.

When I got a chance to talk to Karen at this year's YAPC::NA, I told her (again) how much I had enjoyed the previous talk and how disappointed I was that I had never been able to show it to others. Fortunately, she had polished the talk some more and presented it again. The paper Understanding Volunteers is the essence of the talk I was looking for, and she gave me the link.

If you ever have a need to understand what drives a particular open source or volunteer group, this paper is a real help. Open source projects are as much (or more) about the people as about the technologies. Many of us technologists forget that. Karen obviously doesn't.

Posted by GWade at 10:33 PM. Email comments

April 25, 2009

SVG Sparklines in Perl

For the last few weeks, I've been working on a Perl module for creating Sparklines* in SVG. The original purpose of the project was a demonstration of working with SVG from Perl. It was intended to be an example in a talk I was going to give for our local Perl Mongers group. As usual, it has grown to be much more than that. (I still hope to get back to that talk.<shrug/>)

In the process, I've been exploring a few other ideas that were not part of the original plan. I planned to develop the module as I usually do and then release it to CPAN. I released an early version (something I normally do not do) and got feedback from an interested developer within 24 hours. This was on a barely functional module.

Based on that email exchange and conversations with some local developers, this is turning into a much more robust and flexible module than originally intended. The interface has improved dramatically. There will be more types than originally planned. There are more ways to configure the look of the generated Sparklines. There is now a cookbook explaining how to generate different effects.

I've also put the module on Github as svg-sparkline. Although I've been playing with git off and on for a few months now, this is the first time I've tried to use with it seriously.

Unlike many of my past projects, this one requires more visual design thought than I normally need. In a way, this quick, little project has turned into a way to experiment with several new ideas and skills at once. We'll have to see how this one turns out.

Note:
* A Sparkline is an intense, word-sized graphic intended to convey useful information inline within text. The concept was proposed by Edward Tuft in his book Beautiful Evidence. For more on sparklines, see Tuft's article on the subject.

Posted by GWade at 07:48 PM. Email comments | Comments (1)

January 25, 2009

The Literals of Functional Programming

I was listening to an older episode of Software Engineering Radio where they interviewed Martin Odersky on Scala (Episode 62). In the interview, Odersky made a comment about closures being the literals of functional programming. This statement struck me as surprising. The more I thought about it, the more interesting and subtle the concept became.

In functional programming, functions are first-class values. (OOP advocates often say first-class objects, but this concept is more fundamental than that.) If a function is a value, like an integer is a value, a closure (or anonymous function) is the equivalent of a literal (like 2). This idea has been wandering around in my head for the last few days. The more I think about it, the more interesting it appears.

To get the most that you can out of an analogy, you need to apply what you know from one side of the analogy to the other to see if it gives any insight. Let's start with what we know about literals:

Magic Literals

We all know the problems with magic literals. Leaving them scattered around the code is a guaranteed way to make unmaintainable code. If the same magic literal is used in multiple spots, the making changes is harder than it needs to be. We normally solve this problem by replacing the literal with a defined constant. If that constant is well-named, this improves the readability of the code. (If the constant is not well-named, it can actually make things worse.)

There are a few cases where we may decide to use a literal despite this fact.

The initial index for a loop is almost always 0 (for C, C++, Perl, Java, etc.). There's really no need to name this literal, because it's function is obvious and it will not change (for a given language). Just as importantly, it's hard to come up with a name that means more to us that the value of the constant itself (please don't name it ZERO).

If you are working with date manipulation code, the literals 7 and 12 are obvious enough that we might not choose to make the constants DAYS_PER_WEEK or MONTHS_PER_YEAR. This decision is not quite as obvious, but it would be relatively easy to justify not making a constant. On the other hand, most people would probably prefer MINUTES_PER_DAY to 1440 and SECONDS_PER_DAY to 86400. This shows that if the use of the literal is obvious enough, we may not need to name it. If there's any question about the purpose of the constant, we give it a name.

Another possibility would involve implementing an algorithm from a book that contained a large number of single use magic literals. You would probably keep the literals and reference the original algorithm in a comment rather than add constants that weren't in the original algorithm. In this case, being faithful to the original algorithm trumps concerns over magic literals.

Function Literals

The first thing that is worth considering about anonymous functions from this analogy is the possibility that giving the function a name might be wise. If the function is used in many places, giving it a name is probably good for maintenance. (Just like making a constant out of a numeric literal simplifies maintenance.) Likewise, code containing a large number of anonymous functions is likely to be hard to maintain.

Also like the magic literal issue, there may be cases where the anonymous function is obvious enough that no name is needed. I'm going to propose some examples using Perl for the syntax. This is mostly because Perl has a fairly reasonable syntax for anonymous functions. It also has three operators for manipulating lists that make use of anonymous functions: map, grep, and sort, Let's use map. (The map operator generates a new list by applying an anonymous function to all of the elements of another list.)


@newlist = map { $_*2 } @oldlist;

Once you know that $_ is the argument to the subroutine, it is obvious that this anonymous function doubles its argument. In this context, @newlist is a list where all of the elements are the doubles of the elements of @oldlist. A similarly obvious example (with better named variables) would be:


@elapsed_secs = map { $_*60 } @elapsed_minutes;

This anonymous function converts minutes to seconds by multiplying by 60. Giving the function a name would not really clarify things any. What about


@newlist = map { $_*($_*17 + 33) + 42 } @oldlist;

This example is the equivalent of a magic literal in the code. I can't imagine anyone looking at this and deciding that it is perfectly clear. Much like code containing the magic literal 17, this function should be named. Otherwise, the code is hard to read and maintain.

Filtering with Predicates

Another place that anonymous functions are useful is when filtering a list using grep. Like the map cases above, we can see that simple tests make good function literals.


@positive = grep { $_ > 0 } @unfiltered;

This anonymous function obviously selects positive numbers. Just like the next one selects numbers below a cutoff.


@selected = grep { $_ < $cutoff } @unfiltered.

However, just like the map, we can have examples that would benefit from naming the function.


@filtered = grep { $_ > 3 && $_ < 13 && $_%2 == 0 } @unfiltered;

It's going to be practically impossible to understand this without some help, so turning this anonymous function into a named function is probably worthwhile.

Further Consideration

Like numeric literals, functional literals can make code harder to understand. However, giving all closures names as a knee-jerk reaction is not a valid answer. Consider naming anonymous functions when it would make the code clearer without breaking it. I'm still not sure whether anonymous functions are as bad for maintenance as numeric literals. More thought and experimentation is needed.

So far, I don't feel like I've made it through very many of the implications of anonymous functions being the functional programming equivalent of literals. I'll probably write more later, as more implications come to me.

Posted by GWade at 08:30 PM. Email comments

July 02, 2008

Perl != Regular Expressions

Yesterday, I wrote an essay on a comment made in Jeff Atwood's Coding Horrors blog about regular expressions. While Atwood spends quite a bit of time on the two problems joke and talks passionately about regexes as a tool, he does take a swipe at Perl that seemed somewhat uncalled for.

I have seen Perl bashed by lots of people over the years. Some have never written (or read) any Perl, but still feel qualified to bash the language. I've also been told that the only reason that I could possibly like Perl is if I had not written or maintained anything serious in Perl. When I point to large applications running in a 24/7 data centers that I worked on for years, they normally change the subject. Pointing to the number of financial institutions, research groups, and large corporations that depend on Perl to function is also illuminating.

Regular Expressions

I often see regular expression bashing and Perl bashing tied together. There seems to be this weird meme running around that regexes are the only tool in the Perl toolbox. Both Atwood and Zawinski (see Atwood's post that started this line of thought) seem to take the viewpoint that Perl is nothing but regexes or that Perl somehow forces you to to do everything through regexes.

Anyone who has worked with Perl for very long has seen that the language has very strong support for regex processing. This makes sense because the original goal of the language was text processing and regexes are made for text processing. For many, Perl was their first introduction to industrial strength regexes. Maybe it's not too surprising that they decided to overuse that powerful little tool.

Perl is also a general purpose language that supports OOP as well as a procedural style. It also supports list processing and functional programming. There are modules on CPAN for controlling hardware, accessing databases, biology, and astronomy. There are also natural language processing modules, XML parsers, and web frameworks.

Perl is a powerful, flexible language that some of us use to get actual work done.

Passionate About Perl

As much as some people hate Perl and find it necessary to build up their language of choice by bashing Perl, some of us find the language to be a natural tool for many jobs. I have worked professionally in half a dozen general purpose languages over my career. But for solving a problem quickly, I normally turn to Perl. And I don't just mean for quick and dirty scripts. If I need to solve something in a short period of time and be sure it will work for years, I also often use Perl.

Bjarne Stroustrup once said:

There are only two kinds of programming languages: those people always bitch about and those nobody uses.

I would say that both C++ and Perl definitely fall into the first category.

People often pick on other languages. We've all heard the complaints (that are at best half true). Almost everyone picks on Basic for being a bit of a kiddie language. Cobol is the old-style business language that rots the brain. C++ is too baroque. Python is obsessed with indentation. Lisp has too many parentheses. Staticly typed languages are too obsessive and dynamic languages are either too slow or too loose.

Although the fans of each language might insult other languages in a friendly sort of way, mention Perl and the vitriol begins to fly. I know quite a few people who really like Perl and I know at least as many who truly hate it. As Kathy Sierra pointed out a few years ago If some people don't HATE your product, it's mediocre..

Based on the level of hate that Perl seems to inspire, it's safe to say that the language is definitely not mediocre.

Posted by GWade at 07:15 AM. Email comments

June 25, 2007

On-site at YAPC::NA 2007

As a short break from my normal programming oriented blog entries, I figured I should comment about YAPC::NA 2007 which we (Houston.pm) are hosting. The conference is currently running (June 25 - 27) at University of Houston, Central Campus.

Eight-ish months ago, Jeremy Fluhmann talked us into putting in a bid for YAPC. Despite quite a bit of work it has turned into an amazing learning experience, even before the conference started.

As you might be able to tell from my site, I'm a stereotypical programmer-type. In the process of preparing for the conference, I had to work to learn to deal with people much better than I normally do. It is a lot of work. There were stressful situations. Things went wrong. Things went right. We were stretched and we learned. On top of everything, I had a real chance to meet and work with people just outside my normal comfort zone.

If you ever get an opportunity to run a conference or help organize a conference, I would highly recommend taking that opportunity. If you are like me, you will find this to be much different than you expect and a really good opportunity to work on skills that you may not normally exercise.

Posted by GWade at 04:21 PM. Email comments

July 24, 2006

Review of Higher Order Perl

Higher Order Perl
Mark Jason Dominus
Morgan Kaufmann, 2005

The simplest thing you can say about MJD's Higher Order Perl, is that it is not your ordinary, everyday programming book. It is not even your everyday Perl book. MJD introduces an approach to programming that will be new to most programmers. Even those who have some experience with these techniques will probably gain some insights and tricks.

Many of the techniques introduced in this book will be familiar to users of Lisp or Lisp-derived programming languages. If you haven't worked with one of these languages before, be prepared for an eye-opening approach to Perl and programming in general. If you have worked with one of those languages, you may be surprised to see the techniques that Perl supports.

The book begins with functional programming and recursion. This section gives the grounding you will need to understand the rest of the book. MJD goes on to explain programming with dispatch tables. Although I have been using dispatch tables for years, MJD still showed a couple of techniques that I haven't used. Next came caching, including memoization, and how caching can solve some problems with recursion. The book continues with iterators, streams, currying, parsing, and a large example of declarative programming.

MJD's style is clear and understandable. He gave the best explanation of currying, I've ever seen. He succeeds in showing how these techniques work and how you might use them to improve your own code. Possibly one of the most important points of the book is to show a different approach to solving problems with Perl. As he says in the Preface, many Perl programmers have been writing C programs in Perl for years. Part of the purpose of this book is to point out that there are other ways to solve programming problems. The more ways you have of looking at problems and solutions, the better your chance of solving the next problem.

My only complaint about the book was the long example used for declarative programming. Although this example tied together many of the techniques in the book, it did seem to drag for me. The example showed a declarative solution to a rather complex problem. As a result, it was easy to get lost in the details of implementation and lose sight of the principle being taught.

Overall, I would recommend this book highly to any intermediate or advanced Perl programmer. I am not a certain about recommending the book to a beginning Perl programmer, unless that person already has a background in multiple programming paradigms, including functional programming.

Posted by GWade at 07:06 AM. Email comments

July 04, 2006

Review of Perl Hacks

Perl Hacks
chromatic , Damian Conway, Curtis "Ovid" Poe
O'Reilly, 2006

When I first saw the title Perl Hacks, I was a little unclear what the book would cover. After all, the Perl Cookbook has recipes that span the spectrum from basic to advanced. What would Perl Hacks supply that wouldn't be found elsewhere?

The first few hacks answered those doubts superbly. The first 11 hacks focus on productivity in programming Perl. The first hack shows how to use Firefox shortcuts to make finding Perl module documentation easier. The next couple of hacks focus on getting more out of the Perl Docs. The section continues with ideas for using shell aliases, configuring Vim and Emacs for Perl, enforcing local style with Perl::Tidy, and running Perl tests within your editor. Although I had stumbled into a few of these or seen some of them elsewhere, these hacks were focused specifically on making you more productive, immediately.

The next few sections focus more on programming in Perl, including user interface issues, data manipulation, and module usage. The section on debugging covers several useful techniques. Some apply to any programming problem (binary searching for bugs), others are Perl specific (customizing the Perl debugger). The Developer Tricks and Know Thy Code sections will probably improve your Perl knowledge and skills in a number of ways.

The final section of the book should really push your Perl knowledge and skills. Most of the hacks in this section are pretty advanced. You may never need some of what is shown here. On the other hand, one of these hacks may be just the thing you need to solve the problem you are currently struggling with.

All in all, I was pleasantly surprised by Perl Hacks. Given the authors, I expected the book to cover interesting topics very well. I was initially concerned that the book might just be a rehash of information from other books, but that concern was quickly laid to rest. You may not learn something from every hack, but I'm confident that almost everyone will find something new in this book.

I definitely recommend this book to anyone programming in Perl, whether novice, expert, or anywhere in between.

Posted by GWade at 09:23 AM. Email comments

January 29, 2006

Review of Perl Best Practices

Perl Best Practices
Damian Conway
O'Reilly, 2005

This book is hard to summarize. There is much good advice in this book. Unfortunately, there's also some advice that I found questionable. Conway covers some of important Perl and general programming best practices, including consistent formatting, use of strict and warnings, and the use of version control software. Unlike my standard book on best practices, Code Complete, Conway does not provide much independent support for his assertions. On the obvious best practices (meaning those you agree with), this is not a big issue. However, I did find it difficult to accept suggestions to change coding practices I've developed over almost two decades without any supporting evidence.

Without that evidence, I found some of Conway's arguments to be less than convincing. For example at the beginning of Chapter 2, he states that consistent layout is important, but which particular layout style you use does not matter at all. So far I agree with him completely. Then, he goes on to spend over 25 pages describing his preferred layout style, listing each point as a best practice and spending time justifying his choices. If the particular layout style does not matter, shouldn't we have had one best practice, use a consistent layout style instead of 22 individual layout suggestions elevated to best practice status?

I was also interested to find that more than 10 of the recommended modules were written by Damian Conway. Some of these appear to have been updated on CPAN relatively recently. That makes me wonder how they have had time to become best practice.

Some of his rules appeared to be somewhat contradictory. For instance, we shouldn't use unless because it is not as familiar to many programmers and it is harder to understand complicated boolean expressions in an unless. But, we should use redo to restart a for loop without incrementing the variable when we need more complex flow control. And we should prefer \A and \z in regular expressions, because

They're likely to be unfamiliar to the readers of your code, in which case those readers will have to look them up, rather than blithely misunderstanding them.

Although these suggestions may be good practice and may actually help in writing maintainable code, I find it impossible to detect an underlying philosophy driving this particular set of suggestions.

If you've read this far, you probably have gotten the impression that I hated this book. That is very far from the truth. Damian Conway is a prolific Perl programmer with loads of experience. Much of his advice parallels my own philosophy in writing code, in Perl and in other languages. As I was reading the book, I installed several of his suggested modules and have even modified a few of my Perl programming practices based on his arguments. However, I would be uncomfortable suggesting that a new Perl programmer use this book as the reference on how to program in Perl.

In general, I believe that my biggest problem stems from the expectations I had from the title. If it had been called Damian Conway's Recommended Practices for Perl, I would have been a bit more forgiving. However, by setting itself up as the book on Perl best practices, I feel that the practices in the book need to be more than Conway's recommendations. Supporting evidence or studies would have made it easier to swallow his suggestions where they disagreed with my own practice. Less inconsistency between different rules would have made me more comfortable that he has an underlying strategy instead of listing the part of the language that he, personally, likes. Better disclosure about the modules he wrote and their age, would have made the book feel less like an infomercial in spots.

All in all, I think I would recommend this book to more senior Perl programmers or senior programmers coming to Perl. I would be a little leary of recommending it to novice Perl programmers without some strong suggestions that they take this as one person's view. The really frustrating thing is that I really wanted a book to be the standard I could use to counteract the myth of write-only Perl. Unfortunately, I don't think this book will do that.

All that being said, there is a large amount of good advice in this book. As long as you take the advice with an appropriately-sized grain of salt, this book could improve your Perl code.

Posted by GWade at 01:59 PM. Email comments

November 06, 2005

Review of Perl Testing: A Developer's Notebook

Perl Testing: A Developer's Notebook
Ian Langworth and chromatic
O'Reilly, 2005

This is the first book I have read from the new O'Reilly Developer's Notebook series. Although the style of these books probably won't work for every topic, it works particularly well for a book on testing. Each chapter is organized as a set of labs. These labs walk through some portion of the topic with the goal of developing practical skills.

Each lab revolves around a task. They don't delve into theory, they focus on describing how you perform the task. Unlike O'Reilly's Cookbook series, this is a directed set of tasks. Much like labs in a class, the labs in this book start with basic testing skills and work to build more advanced testing skills. The goal of this set of labs is to help you become proficient in the skills needed for doing quality unit testing of Perl code.

I have been doing testing with Perl for some years now, so the first few labs were review. But, the labs swiftly escalated to more advanced topics that I was either light on or had not explored at all. In addition to labs about Test::Simple, Test::More, and Test::Harness, the book covers:

  • testing the POD documentation in your modules
  • coverage testing
  • testing exceptions generated by code
  • testing warning generated by code
  • building testing libraries to simplify testing
  • mocking objects
  • overriding system calls
  • testing databases
  • testing websites

and many more topics related to testing. This little book is packed with practical information and labs that help you improve the skills you need to build quality testing for your Perl code.

I really don't expect this book to become a well-worn reference book that stays near my desk at all times. However, I don't expect to let it get far away. Since few of us need to use all of our testing skills on every project, some skills become rusty over time. Anytime I find some of my testing skills have gotten rusty, I expect to grab this book and run through the appropriate labs to sharpen the skills I need.

If you want to know why you should be unit testing your Perl code, there are many books out there that will explain. If you are looking for an explanation of Test Driven Development, this is not the book to read. Once you have decided that testing is important to you and your projects, this is the book you need. I would not say that there are no other resources for learning this material, but this may be the fastest way to build the appropriate skills that I've seen.

It also helps that the authors have a very relaxed style that helps you feel more like they are working along side you than lecturing at you. The titles of the sections are very casual (How do I do that?, What just happened?, etc.) This makes it easy to read the next part and get back to working on the meat of the lab.

I would recommend this book to anyone writing Perl code. We all need to be doing testing to improve our code and our designs. The key difference between good testing and bad testing is the skills to make every test count. This book teaches those skills.

Posted by GWade at 07:48 AM. Email comments

March 07, 2004

Review of Perl for Web Site Management

Perl for Web Site Management
John Callender
O'Reilly, 2002

This book may be one of the best books I've ever seen for getting Perl used in a place where it is sorely needed.

Many people developing web-based applications are not programmers. They learned to use some HTML authoring tool and progressed from there. Many of them never quite get the idea of automating the grunt work of their jobs. This book tries to introduce these people to Perl as a labor-saving device.

If you are doing any form of web site maintenance, this book is worth a read. If you are a programmer working on web sites, you are probably doing most of what this book teaches. But, if your background is not in programming, this book will probably increase your productivity dramatically.

Posted by GWade at 02:52 PM. Email comments

February 25, 2004

Review of Mastering Regular Expressions

Mastering Regular Expressions
Jeffery E. F. Friedl
O'Reilly, 1997

If you use regular expressions on a regular basis, or if you've used them a little but want to get better, this is a book you need. I had been working with regular expressions for over ten years when I first read this book. I was used to helping other people debug their regular expressions and thought I knew them very well. This book improved my regular expressions tremendously.

The book covers multiple regular expression implementations, including AWK, grep, Tcl, GNU Emacs and Perl 5 regular expressions. Friedl does a good job of covering basic regular expression concepts before going on to more advanced topics. Some of these include different types of regexp engines and their effects on the expressions you write, and greediness. He covers some regexp gotchas including regular expressions that may never terminate.

Throughout the book are a number of useful techniques that will improve your daily use of regular expressions.

Mastering Regular Expressions is highly recommended.

Posted by GWade at 06:48 AM. Email comments

January 17, 2004

Regular Expression Maintainablity

perl.com: Maintaining Regular Expressions [Jan. 16, 2004]

Aaron Mackey does a wonderful job of suggesting more maintainable regular expression idioms. His use of (?{}) to assign the results of capturing parenthesis inline was particularly interesting to me. I may have seen it before, but this is the first time it made sense.

The article goes into some serious magic later including deferred execution of the (?{}) blocks and Regexp::Fields.

Posted by GWade at 06:09 PM. Email comments

January 16, 2004

Unit tests that should fail

I was doing a little research on the Java JUnit test framework and ran across the article The Third State of your Binary JUnit Tests.

The author points out that in many test sets there are ignored tests as well as the passing and failing tests. As the author says, you may want to ignore tests that show bugs that you can't fix at this time. He makes a pretty good case for this concept.

The Perl Test::More framework takes a more flexible approach. In this framework you can also have skipped tests and todo tests in addition to tests that actually need to pass. These two different types of tests have very different meanings.

Skipped tests are tests that should not be run for some reason. Many times tests will be skipped that don't apply to a particular platform, or rely on an optional module for functionality. This allows the tests to be run if the conditions are right, but skipped if they would just generate spurious test failures.

Todo tests have a very different meaning. These tests describe the way functionaly should work, even if it doesn't at this time. The test is still executed. But, if the test fails, it is not treated as a failure. More interestingly, if a todo test passes, it is reported as a failure because the test was not expected to pass. This allows bugs and unfinished features to be tracked in the test suite with a reminder to update the tests when they are completed.

Unlike the idea in the referenced article, these two separate mechanisms don't ignore tests that cannot or should not pass. Instead, we can document two different types of non-passing tests and still monitor them for changes.

Posted by GWade at 12:58 PM. Email comments

January 15, 2004

Perl as a "dinosaur"?

Someone asked a question about updating SVG dynamically from a server on the SVG Developers list this morning. One of the (many) responses pointed to an article on SVG server-side.

As usual, I went to check it out to see if it might hold some tidbits I could use. Or maybe, it could be a resource I might recommend. While scanning the article, I found this little quote

Perl is the dinosaur among web scripting languages, its market share (when it comes to server side web scripting) getting smaller...

They go on to point out that in Perl you have to manually set the header.

I find it amusing that people that want to show Perl in a bad light ignore modules like CGI.pm that help to give Perl most of the support you need for web scripting. CGI.pm has been out there for a long, long time. It's been part of the standard distribution since version 5.004.

To give the authors credit, they do mention the SVG.pm Perl module for generating SVG using Perl objects.

Posted by GWade at 09:38 AM. Email comments