Welcome to WebmasterWorld Guest from 54.147.212.98

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

Helpful Perl tips

Things I wish I knew when I started

   
1:40 pm on Jul 14, 2005 (gmt 0)

10+ Year Member



One of the core philosophies of Perl is TIMTOWTDI - There Is More Than One Way To Do It. When I started with Perl I hacked and slashed my way through things and ended up churning out a lot of bad code. Over time I learned some things that cleaned up my code and reduced my error rate. Here are some of them.

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

5:02 pm on Jul 14, 2005 (gmt 0)

WebmasterWorld Administrator jatar_k is a WebmasterWorld Top Contributor of All Time 10+ Year Member



nice post SeanW, thanks

added to library

any other helpful tips are welcome

4:59 am on Jul 18, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Flagged this post. Thanks SeanW :)
5:23 am on Jul 19, 2005 (gmt 0)

10+ Year Member



Good post, thanx ;)

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 :(

11:46 pm on Jul 19, 2005 (gmt 0)



Definitely use 'use warnings' (or -w on the /usr/bin/perl line)... I can't tell you how many hours this has saved me.

-Bill