A Big List of Stuff You Want
Perl Is Not Enough
Perl has lots of useful built-in functions. Everybody loves
Maybe we only want the first element, though. There's more than one way to do it – here are two:
Fortunately, we've got List::Util:
It's easy to read, easy to write, and works efficiently, stopping at the first hit.
List::Util has a bunch of useful stuff like this. It has routines for summing up numbers, or finding maxima and minima. It's got a
shuffle routine for randomizing lists, which you should use. I can't tell you how many horrible reimplementations of List::Util's shuffle I've deleted over the years.
Even more importantly, though, it provides a
reduce is a really common higher-order function, often called
fold. You can use it to build lots of other really useful behavior. For example, we might use it to reimplement
sum, since the one that comes with List::Util stinks¹.
reduce is called with a function (usually written as a block) and a list of inputs. If there's only one item in the list, it returns that. Otherwise, it calls the function with the first two items and makes the result the new head of the list. Confused?
@numbers is empty, we return 0. If
@numbers contains (1, 2, 3), this is what happens:
We have more than one item in the list! Our input is (0, 1, 2, 3)
Shift off 0 and 1, and unshift the result back onto the input.
Now our input is (1, 2, 3)
Shift off 1 and 2, and unshift the result back onto the input.
Now our input is (3, 3)
Shift off 3 and 3, and unshift the result back onto the input.
Now our input is (6)
There's only one input! Return it!
Lots of stuff can get implemented in terms of
reduce. Knowing how (and when) to use it is really useful. In fact, the List::Util documentation points out how several of its functions could have been written as folding constructs instead.
List::Util is Not Enough
List::Util's documentation also lists a few things that people have proposed for inclusion over the years, like
The docs say that
any has been omitted because it's so easy to write inline (especially if you have
first). Still, why not make them available? List::MoreUtils does just that, providing all the routines List::Util declined to and much more.
List::MoreUtils also helps get rid of many occurances of
%seen, one of my least favorite often-seen variables:
And it provides the terribly-named
natatime for processing n elements at a time:
There's a Lot More
I've only given a very thin gloss over List::Util, and barely scratched the surface of List::MoreUtils. The point is that these two libraries are useful all the time. If you haven't used them yet, it's almost certain that you could've saved time by using them a few times. Learn what's in them, and consider them a tool you can reach for without thinking about it.
In fact, to help you not have to think about it, don't use either of them! Instead, use List::AllUtils, which provides all the routines of the other two, combined into one library so you don't have to try to remember whether
minmax is from Util or MoreUtils².
List::Util's sum returns undef, instead of 0, for an empty input list.
maxare from Util, but
minmaxis from MoreUtils