1. use strict. Always. It catches many stupid mistakes such as typos in variable names that take a while to debug otherwise.
[perl]
#!/usr/bin/perl
use strict;
...
[/perl]
People also advise to turn on warnings (perl -w), I've never gotten into that, but I don't discourage its use.
2. CPAN. Rocks. Don't reinvent the wheel. If you can find a module to do what you want, use it. If you find something close, see if you can subclass it to get the specific functionality you want. Learn to use the cpan interface (such as the readme command to read the docs before you install). Often there are multiple modules that do the same thing, and reading through the docs will help you figure out which is best for you.
3. Data::Dumper and the Debugger. Timesavers.
Data::Dumper will spit out a data structure to the console. I find it is the fastest way to get your head around something, especially when dealing with the result of a function you didn't write (such as a CPAN module).
Ever seen something like this?
$ perl -e 'my $a = { a=>'b'}; print $a;'
HASH(0x92a9c18)
Dumper will make it more clear:
perl -MData::Dumper -e 'my $a = { a=>'b'}; print Dumper $a;'
$VAR1 = {
'a' => 'b'
};
In a more useful example:
[perl]
use Data::Dumper;
my $foo = somefunction(); # what format is the result in?
print $foo; # useless
print Dumper $foo; # now you understand what's in $foo
[/perl]
4. map/grep
Often you have to iterate through an array and do something to each element, which you probably use a foreach loop to do. There are some intrinsic commands that do this called map and grep.
These two perl commands make code much more clear because they show intent. Ever done something like this?
[perl]
foreach my $i (@array) {
push @foo, $i if ($i =~ /foo/);
}
[/perl]
The intent here is to pull out all array elements that have foo in them. Grep does the same thing, but it's blindingly obvious to a reader that you're doing it:
[perl]
@foo = grep /foo/, @array;
[/perl]
Similarily, if you want to do the same thing to each element, use map. Rather than
[perl]
foreach my $i (@array) {
$i =~ s/foo/bar/;
push @out, $i;
}
[/perl]
you can do
[perl]
@out = map { s/foo/bar/; $_ } @array;
[/perl]
Here, map is passed a block of code within { }. Each iteration, $_ holds the current value. In the example, the substitute is performed on $_ (since that's the default). The "; $_" makes the result of the block equal to $_, since the return value of a regexp is the number of substitions (try it without the ;$_ and see what I mean).
You can of course use functions:
[perl]
@uppercase = map { uc } @array;
[/perl]
5. Quoting
These are more typing savers.
Define an array:
[perl]
my @array = qw/element1 element2 element3/;
[/perl]
Strings:
[perl]
$name = "Sean";
$test1 = qq/Hello $name/; #Interpolated
$test2 = q/Hello $name/; #Non interpolated
print "$test1\n$test2\n";
[/perl]
Outputs:
Hello Sean
Hello $name
There are some more (rx for regexp, qx for system commands)
6. Consistency
Strive to remain consistent in the way you do things. Don't use 4 different modules to do the same thing across 4 different programs. Learning new things and improving means some things will change, but try to be consistent otherwise.
7. Write with the idea it will be used elsewhere
This could be the subject of an essay, but:
- Break up stuff into functions so at least you can copy and paste.
- Avoid globals and making assumptions within a function
- Build your own packages
- Use configuration files (YAML) and command line parameters (Getopt::Long) to alter the program's behaviour
8. References are your friend
This could be another essay. I rarely use arrays and hashes, instead I use references to them. It allows me to build more complex data structures.
[perl]
my %hash = ( a => "b" ); # no references
my $hashref = { $a => "b" }; # references
[/perl]
Good luck!
Sean
Edit: Removed pre and fixed tags since they don't seem to work
At the same time I'd add a paragraph about HASHes usage importance.
Some guru's say about this like : if you do not "hash-thinking" yet, you do not use Perl properly.
I'm still not "hash-thinking" - always try to use arrays instead of hashes first. And I DO feel I've been missing a lot :(
-Bill