PERL - Tips & snippets

mail

PERL's // and //= operators

// :

  • expression1 // expression2
    returns the value of expression1 if it's defined, otherwise, the value of expression2
  • equivalent to :
    defined(expression1) ? expression1 : expression2
  • This is very useful for providing default values for variables.

//= :

  • //= is the assignment operator version of //
  • $i //= '08';
    is a shorthand for :
    $i = (defined $i) ? $i : '08';

Check for support :

The // and //= appeared with Perl 5.10.0. To quickly check whether they are supported, try these :
  • perl -e 'my $i = $undefinedVariable // 2; print $i;'
  • perl -e 'my $i //= 2; print $i;'
Both should return : 2.
mail

PERL variables

This article may sound like "stating the obvious" (which is not completely wrong). However, since :
  • it's been ages I've not written PERL
  • similar stuff in different languages have different names
  • in PERL, a single $, %, @ or & changes the meaning of things
  • Nothing is ever obvious for everybody.
... better stating the obvious rather than writing poor code
Notation Variable type Details
$myVariable scalar
@myVariable array aka list in Python. Items are referenced by their (0-indexed) position in the array.
%myVariable hash aka associative array or "key-value" pairs (details)
mail

CPAN libraries

Stop f**king around with CPAN while installing libs (source) :

cpanminus (aka App::cpanminus) is a script to get, unpack, build and install modules from CPAN and does nothing else. It's dependency free (can bootstrap itself), requires zero configuration, and stands alone. When running, it requires only 10MB of RAM.
To install it (as root) :

  1. apt install curl make
  2. curl -L http://cpanmin.us | perl - App::cpanminus
    --> Working on App::cpanminus
    Fetching http://www.cpan.org/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7044.tar.gz ... OK
    Configuring App-cpanminus-1.7044 ... OK
    Building and testing App-cpanminus-1.7044 ... OK
    Successfully installed App-cpanminus-1.7044
    1 distribution installed
  3. From then on, install modules by executing (as root if necessary) :
    • cpanm Foo::Bar
    • cpanm Nagios::Plugin::WWW::Mechanize
    • cpanm git://github.com/perldork/Nenm--Utils.git
    • OR (if tests fail) : cpanm -n Foo::Bar
      -n means --notest
  4. Enjoy !
Nenm::Utils : download from https://github.com/perldork/Nenm--Utils, then copy it in the PERL libs tree (/usr/local/lib/perl/5.10.1/Nenm/Utils.pm)

Detect whether a library is installed (method 3) :

method 1 :

  1. from the system shell : cpan URI::telnet cAsE SeNsItIvE !!!
  2. If this module is installed, it will return :
    URI::telnet is up to date (undef).
    Or it will try to install it. On success, this will end on :
    /usr/bin/make install -- OK
    Otherwise :
    Warning: Cannot install URI::Telnet, don't know what it is.
    Try the command
    
    	i /URI::Telnet/
    
    to find objects with matching identifiers.
    

method 2 :

Considering we're looking for the URI::telnet library, run :
  • find $(perl -e 'print "@INC"') -iname 'telnet.pm' | grep -i "uri/"
  • or : find $(perl -V | egrep "/site_perl/[0-9]\.[0-9]\.[0-9]$" | sort -r | head -n 1) -iname 'telnet.pm' | grep -i "uri/"

method 3 :

perl -e "use IO::socket"
No error message means the module is installed.

Install a library (Net::DNS) on Windows :

  • normal install : just open a system shell and run : cpan Net::DNS
  • force install :
    1. open a system shell
    2. perl -MCPAN -e shell
    3. force install Time::HiRes
    4. exit
  • checking install :
    • from the system shell : cpan Time::HiRes, which should output :
      xxx is up to date
    • OR from the CPAN shell (perl -MCPAN -e shell) : i / Time::HiRes
mail

PERL cryptic special variables

Variable Name Usage Details
Error management
$@ error code / message detected by the PERL interpreter The variables $@, $!, $^E and $? contain information about different types of error conditions that may appear during execution of a Perl program. The variables are shown ordered by the "distance" between the subsystem which reported the error and the Perl process. (source)
$! error code / message detected by the C library
$^E error code / message detected by the operating system
$? error code / message detected by an external program
Other stuff
@_ array containing all the arguments sent to a subroutine
  • To load arguments passed to a subroutine with : mySubRoutine('foo','bar','baz');
    Do in subroutine : my ($arg1, $arg2, $arg3)=@_;
    Or use $_[n], being the nth argument passed to the subroutine (starting at 0)
  • my(@args)=@_; is used mainly when the argument is a list of data to process.
  • If a single argument is sent to the sub, it's more convenient to use shift :
    $result=mySub($foo);
    sub mySub {
    	my $myVariable=shift;
    	...
    	}
$_[n] the nth argument passed to the subroutine (starting at 0)
$/ the input record separator. Defaults to "\n".
$_ each element of LIST, alias to the list value
$#myArray index of the last element of the array myArray. Since Perl arrays start at element 0, this number will be one less than the length of the array.
mail

structures

mail

hashes

2 ways to declare/use hashes :

#!/usr/bin/perl -w
use strict;

my $key;
my $value;

my $hashTable = { name => 'Jeff', age => 23 };			$-named, data between curly brackets
foreach $key (keys %$hashTable) {
	$value = $hashTable->{$key};				de-referenced with the -> operator
	print "$key :\t$value\n";
	}

print "\n";

my %hashTable2 = ( firstname => 'Bob', how_old => 22 );	%-named, data between parenthesis
foreach $key (keys %hashTable2) {
	$value = $hashTable2{$key};				no de-reference operator needed
	print "$key :\t$value\n";
	}
age :	23
name :	Jeff

firstname :	Bob
how_old :	22
Details on Dereferencing.

hash of (anonymous) hashes (source) :

my %config = (
	objects		=> {...},
	commands	=> {...},
	misc		=> {...},
	);



foreach my $topic (keys %config) {	# parse the indices of '%config'. the current index at each iteration is stored into $topic
	print '$topic : '.$topic.EOL;
	# since we're parsing a hash of hashes, $config{$topic} is a hash itself (casted to use the 'keys' function)
	foreach my $data (keys %{$config{$topic}}) {
		print '$data : '.$config{$topic}{$data}.EOL;
		}
	}
print $config{'hosts'}{'outputFile'};