Monday, June 7, 2010

Arguments By Reference

Modify scalar, hash and list through a subroutine.
#!/usr/bin/perl -w
use strict;

my $name;
my %contacts;
my @children;

&my_function(\$name, \%contacts, \@children);


print "Name = $name\n";

foreach my $key ( keys(%contacts) ) {
    print "$key = $contacts{$key}\n";
}
 
foreach my $child (@children) {
    print "Child = $child\n";
}

sub my_function() {
    my $ref_name      = $_[0];
    my $ref_contacts  = $_[1];
    my $ref_children  = $_[2];
    
    $$ref_name = "Harry";
    $$ref_contacts{'home'} = '1234567890';
    $ref_contacts->{'work'} = '9876543210';

    push(@$ref_children, 'James');
    push(@$ref_children, 'Mary');

    print "Name = $$ref_name\n";
    
    foreach my $key ( keys(%$ref_contacts) ) {
        print "$key = $$ref_contacts{$key}\n";
    }
    
    foreach my $child (@$ref_children) {
        print "Child = $child\n";
    }
    print "\n";       
}

Saturday, June 5, 2010

Handle Command Line Arguments

Command line argument is commonly use in passing in the configuration to a Perl script. Fortunately, Perl's core module come with a parsing library i.e. GetOpt::Long which ease the parsing of arguments.

Here is the sample code:

#!/usr/bin/perl
use Getopt::Long;

my @files = ();
my $outputfile;

# Checking for missing arguments
if (@ARGV == 0 || 
  !GetOptions("input=s{1,}" => \@files, 
              "output|dest=s" => \$outputfile) || 
  @files == 0 || 
  !defined($outputfile)) { 
  # Print Usage
  print "Invalid arguments!\n"; 
  exit 1;
}
print "Total Input File: " . @files . "\n";
foreach my $file (@files) {
  print "-> $file\n";
}
print "Output File: $outputfile\n";

Output:


D:\>GetOptions.pl -i a.txt b.txt -d my.txt
Total Input File: 2
-> a.txt
-> b.txt
Output File: my.txt
The checking for the missing arguments:
  • Check for zero argument: if (@ARGV == 0 ||
  • Check options are in "s" or "o" or "d": !GetOptions("input=s{1,}" => \@files, "output|dest=s" => \$outputfile)
  • Check for no input files: @files == 0
  • Check for missing output file: !defined($outputfile)
To get multiple values the option, you can use "input=s{1,}", it will store the values into a list (@files).

NOTE: In Perl, a subroutine parameter start with back slash ("\") e.g. \@files, indicates pass by reference. It means the parameter can be changed through the subroutine.