Perl often suffers from its history. While it is great that there are so many online tutorials and code samples out there for new Perl developers to learn from, they sometimes miss out on all of the useful new code that has been created since the article was written. Here are a few CPAN modules that are, in my opinion, under-used by new developers.
These modules are great for several reasons. The most compelling ones are there is lesss code for you to write/debug than not using these modules, the resuling code is often clearer to your fellow developers, and in many cases the module will out perform your hand hacked code.
List manipulations
There are two list related modules you should familiarize yourself with. They are List::Util and it's cousin List::MoreUtils.
Need to shuffle the values in an array? Don't reinvent the wheel, use List::Util's shuffle function.
use strict;
use warnings;
use List::Util qw( shuffle );
my @array = qw( 1 2 3 4 5 6 7 8 9 );
my @shuffled = shuffle( @array );
Need to make a list only contain unique values? You can use the method found in the Perl Cookbook, or you can use the simpler uniq() function from List::MoreUtils like so:
use strict;
use warnings;
use List::MoreUtils qw( uniq );
my @array = qw( 1 1 2 2 3 3 4 4 5 5 );
my @unique_values = uniq( @array );
Not to mention List::MoreUtils' implementation is done in C, so it is much faster than a Pure Perl implementation. I once saw this improve the performance of a large web application by 5% because the developers were uniquing several lists for each page view.
Be sure to also check out the other functions in these two modules such as any(), all(), first(), max(), etc. While you will have to install List::MoreUtils from CPAN, List::Util is part of Perl core.
Merging Hashes
While you can use the simple:
my %merged_hash = ( %hash_one, %hash_two );
Someitmes you need a bit more power, enter Hash::Merge. It gives you several options on how to handle conflicting keys, based on a left/right order, or by storage method. Or you can even control whether or not your data is cloned on not. I find this very useful for merging in command line arguments against a configuration file.
Speaking of configuration options and files....
Repeat after me. I will not write my own configuration parsing code. I will not invent my own configuration file format. I will not parse my own command line options without a damn good reason.
Why waste your time on the most boring part of your code? Use one of the already existing modules and configuration file formats. This saves you time, debugging headaches, and makes the configuration file syntax familiar to your users.
I strongly suggest looking into Getopt::Long for handling command line arguments. It might take you a bit of time to get used to this module, but once you're over the initial learning curve you'll wonder why you ever bothered doing this by hand in the first place.
If you like Apache style configuration files (who doesn't?), start using Config::General and cut your configuration processing code into a use statement and a couple of lines of code. Or if you happen to prefer .INI style configuration files take a look at Config::Tiny.