Monday, January 23, 2012

How to change @INC to find Perl modules in non-standard locations

If you would like to just test a newer version of a module, I'd recommend the command line flag: perl -I /path/to/lib.
   perl -I /home/foobar/code  script.pl
  
If you are installing lots of modules in a private directory then I'd probably use PERL5LIB though we'll also see local::lib that does this for you.
   export PERL5LIB=/home/foobar/code
  
use lib is used in two cases:
  
One: When you have a fixed, but not standard company-wide environment in which you put modules in a common standard location.

Two: When you are developing an application and you'd like to make sure the script always picks up the modules relative to their own location. We'll discuss this in another post.

use lib '/home/foobar/code';
use My::Module;

How to capture and save warnings in Perl

  #!/usr/bin/perl
  use strict;
  use warnings;

  local $SIG{__WARN__} = sub {
    my $message = shift;
    logger('warning', $message);
  };

  my $counter;
  count();
  print "$counter\n";
  sub count {
    $counter = $counter + 42;
  }


  sub logger {
    my ($level, $msg) = @_;
    if (open my $out, '>>', 'log.txt') {
        chomp $msg;
        print $out "$level - $msg\n";
    }
  }

Filtering values using Perl grep

  Filter out small numbers

  my @numbers = qw(8 2 5 3 1 7);
  my @big_numbers = grep {$_ > 4} @numbers;
  print "@big_numbers\n";      # (8, 5, 7)


Filter out the new files

  my @files = glob "*.log";
  my @old_files = grep { -M $_ > 365 } @files;
  print join "\n", @old_files;

Text::CSV_XS module example in perl

CSV
------

 Tudor,Vidor,10,Hapci
 Szundi,Morgo,7,Szende
 Kuka,Hofeherke,100,Kiralyno
 Boszorkany,Herceg,9,Meselo

   #!/usr/bin/perl
  use strict;
  use warnings;

  my $file = $ARGV[0];
  
  my $sum = 0;
  open(my $data, '<', $file) or die "Could not open '$file' $!\n";

  while (my $line = <$data>) {
    chomp $line;

    my @fields = split "," , $line;
    $sum += $fields[2];
  }
  print "$sum\n";



OR


  #!/usr/bin/perl
  use strict;
  use warnings;

  use Text::CSV_XS;
  my $csv = Text::CSV_XS->new({ sep_char => ',' });

  my $file = $ARGV[0];

  my $sum = 0;
  open(my $data, '<', $file) or die "Could not open '$file'\n";
  while (my $line = <$data>) {
    chomp $line;

    if ($csv->parse($line)) {

        my @fields = $csv->fields();
        $sum += $fields[2];

    } else {
        warn "Line could not be parsed: $line\n";
    }
  }
  print "$sum\n";