Tuesday, September 28, 2010

4 Perl concepts to scare off Beginners

Perl [5.8.6] is a relatively easier language to learn and program, but a tough one if you are trying to read someone's else code. The features in Perl programming language go well beyond, what a beginner is expected to know.

Typeglobs

Today, I just scared off a guy by throwing at him the concept of a typeglob. I conf'ess, that at the time of writing this blog, even I am not clear of the concept of typeglob's. But the point of the blog is to find concepts that Perl beginners don't care to learn about.
Typeglobs are Perl's internal datatype to hold entries in Symbol Tables. Better if you read it from perlmod.

Tie

Well, you can modify the behavior of a normal scalar, array, hash or file handle by using tie. Read more at perltie.

Closures

Not going into technical definition of closures, it's usage for generating iterators is interesting.

Here's a code to demonstrate the usage of closure for reading a tab separated file.

# Closure use case. Here $itr is our closure which will be used as an iterator.
# In Perl terminology, $itr is just a subroutine reference
my $itr = tabfile_itr($ARGV[0], "\t");
while (my $row = $itr->()) {
    # Let's say tabular file has three columns namely name, age and rank
    print "$row->{name} with age $row->{age} has a rank of $row->{rank}\n";
}

# Here's the closure factory. This function takes a file name and a separator
# and returns an iterator that gives a hash reference for each row.
sub tabfile_itr {
    my ($file, $seperator) = @_;
    # Open file
    open(my $fh, "<", $file) or die $!;
 
    # Get the header of file and split by separator
    my $hline = <$fh>;
    chomp $hline;
    my @headers = split $seperator, $hline;

    # Now this thing is called the closure
    my $closure =  sub {
        # The file handle "$fh" was lexically scoped but it will stay
        # statically scoped as long as the $closure is referenced
        my $line = <$fh>;
        chomp $line;
  
        # This is an important part, to break the recursion.
        return unless (defined $line);
  
        # Another lexically scoped variable used in this closure is
        # @headers. To understand each column in the file, we need to
        # have a record of @headers.
        my %col_hash;
        @col_hash{@headers} = split $seperator, $line;
        return \%col_hash;
    };
    return $closure;
}

Read more at perlfaq and perlsub. More closure as iterators examples at perl.com.

use vs require

This is an easy one. "use" runs in the BEGIN block and calls the import function of the package after "require"ing the package. Read more at perldoc -f use.

No comments:

Post a Comment