Perl - Embedded Documentation

You can embed Pod (Plain Old Text) documentation in your Perl modules and scripts. Following is the rule to use embedded documentation in your Perl Code −
Start your documentation with an empty line, a =head1 command at the beginning, and end it with a =cut command and an empty line.
Perl will ignore the Pod text you entered in the code. Following is a simple example of using embedded documentation inside your Perl code −
#!/usr/bin/perl

print "Hello, World\n";

=head1 Hello, World Example
This example demonstrate very basic syntax of Perl.
=cut

print "Hello, Universe\n";
When above code is executed, it produces the following result −
Hello, World
Hello, Universe
If you're going to put your Pod at the end of the file, and you're using an __END__ or __DATA__ cut mark, make sure to put an empty line there before the first Pod command as follows, otherwise without an empty line before the=head1, many translators wouldn't have recognized the =head1 as starting a Pod block.
#!/usr/bin/perl

print "Hello, World\n";

while(<DATA>){
  print $_;
}

__END__

=head1 Hello, World Example
This example demonstrate very basic syntax of Perl.
print "Hello, Universe\n";
When above code is executed, it produces the following result −
Hello, World

=head1 Hello, World Example
This example demonstrate very basic syntax of Perl.
print "Hello, Universe\n";
Let's take one more example for the same code without reading DATA part −
#!/usr/bin/perl

print "Hello, World\n";

__END__

=head1 Hello, World Example
This example demonstrate very basic syntax of Perl.
print "Hello, Universe\n";
When above code is executed, it produces the following result −
Hello, World

What is POD?

Pod is a simple-to-use markup language used for writing documentation for Perl, Perl programs, and Perl modules. There are various translators available for converting Pod to various formats like plain text, HTML, man pages, and more. Pod markup consists of three basic kinds of paragraphs −
  • Ordinary Paragraph: You can use formatting codes in ordinary paragraphs, for bold, italic, code-style , hyperlinks, and more.
  • Verbatim Paragraph: Verbatim paragraphs are usually used for presenting a codeblock or other text which does not require any special parsing or formatting, and which shouldn't be wrapped.
  • Command Paragraph: A command paragraph is used for special treatment of whole chunks of text, usually as headings or parts of lists. All command paragraphs start with =, followed by an identifier, followed by arbitrary text that the command can use however it pleases. Currently recognized commands are −
=pod
=head1 Heading Text
=head2 Heading Text
=head3 Heading Text
=head4 Heading Text
=over indentlevel
=item stuff
=back
=begin format
=end format
=for format text...
=encoding type
=cut

POD Examples

Consider the following POD −
=head1 SYNOPSIS
Copyright 2005 [TUTORIALSOPOINT].
=cut
You can use pod2html utility available on Linux to convert above POD into HTML, so it will produce following result −

Copyright 2005 [TUTORIALSOPOINT].

Next, consider the following example −
=head2 An Example List

=over 4
=item * This is a bulleted list.
=item * Here's another item.
=back
=begin html
<p>
Here's some embedded HTML.  In this block I can
include images, apply <span style="color: green">
styles</span>, or do anything else I can do with
HTML.  pod parsers that aren't outputting HTML will
completely ignore it.
</p>

=end html
When you convert the above POD into HTML using pod2html, it will produce following result −

An Example List

  • This is a bulleted list.
  • Here's another item.
Here's some embedded HTML. In this block I can include images, apply styles, or do anything else I can do with HTML. pod parsers that aren't outputting HTML will completely ignore it.

Perl - Process Management

You can use Perl in various ways to create new processes as per your requirements. This tutorial will list down few important and most frequently used methods of creating and managing Perl processes.
  • You can use special variables $$ or $PROCESS_ID to get current process ID.
  • Every process created using any of the mentioned methods, maintains its own virtual environment with-in %ENV variable.
  • The exit() function always exits just the child process which executes this function and the main process as a whole will not exit unless all running child-processes have exited.
  • All open handles are dup()-ed in child-processes, so that closing any handles in one process does not affect the others.

Backstick Operator

This simplest way of executing any Unix command is by using backstick operator. You simply put your command inside the backstick operator, which will result in execution of the command and returns its result which can be stored as follows −
#!/usr/bin/perl

@files = `ls -l`;

foreach $file (@files){
   print $file;
}

1;
When the above code is executed, it lists down all the files and directories available in the current directory −
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root  574 Sep 17 15:16 index.htm
drwxr-xr-x 3  544  401 4096 Jul  6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root   71 Sep 17 15:16 test.pl
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy

The system() Function

You can also use system() function to execute any Unix command, whose output will go to the output of the perl script. By default, it is the screen, i.e., STDOUT, but you can redirect it to any file by using redirection operator > −
#!/usr/bin/perl

system( "ls -l")

1;
When above code is executed, it lists down all the files and directories available in the current directory −
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root  574 Sep 17 15:16 index.htm
drwxr-xr-x 3  544  401 4096 Jul  6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root   71 Sep 17 15:16 test.pl
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy
Be careful when your command contains shell environmental variables like $PATH or $HOME. Try following three scenarios −
#!/usr/bin/perl

$PATH = "I am Perl Variable";

system('echo $PATH');  # Treats $PATH as shell variable
system("echo $PATH");  # Treats $PATH as Perl variable
system("echo \$PATH"); # Escaping $ works.

1;
When above code is executed, it produces the following result depending on what is set in shell variable $PATH.
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
I am Perl Variable
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

The fork() Function

Perl provides a fork() function that corresponds to the Unix system call of the same name. On most Unix-like platforms where the fork() system call is available, Perl's fork() simply calls it. On some platforms such as Windows where the fork() system call is not available, Perl can be built to emulate fork() at the interpreter level.
The fork() function is used to clone a current process. This call create a new process running the same program at the same point. It returns the child pid to the parent process, 0 to the child process, or undef if the fork is unsuccessful.
You can use exec() function within a process to launch the requested executable, which will be executed in a separate process area and exec() will wait for it to complete before exiting with the same exit status as that process.
#!/usr/bin/perl

if(!defined($pid = fork())) {
   # fork returned undef, so unsuccessful
   die "Cannot fork a child: $!";
}elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
  
} else {
   # fork returned 0 nor undef
   # so this branch is parent
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";

}

1;
When above code is executed, it produces the following result −
Printed by parent process
Printed by child process
Tue Sep 17 15:41:08 CDT 2013
Completed process id: 17777
The wait() and waitpid() can be passed as a pseudo-process ID returned by fork(). These calls will properly wait for the termination of the pseudo-process and return its status. If you fork without ever waiting on your children usingwaitpid() function, you will accumulate zombies. On Unix systems, you can avoid this by setting $SIG{CHLD} to "IGNORE" as follows −
#!/usr/bin/perl

local $SIG{CHLD} = "IGNORE";
 
if(!defined($pid = fork())) {
   # fork returned undef, so unsuccessful
   die "Cannot fork a child: $!";
}elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
  
} else {
   # fork returned 0 nor undef
   # so this branch is parent
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";

}

1;
When above code is executed, it produces the following result −
Printed by parent process
Printed by child process
Tue Sep 17 15:44:07 CDT 2013
Completed process id: -1

The kill() Function

Perl kill('KILL', (Process List)) function can be used to terminate a pseudo-process by passing it the ID returned by fork().
Note that using kill('KILL', (Process List)) on a pseudo-process() may typically cause memory leaks, because the thread that implements the pseudo-process does not get a chance to clean up its resources.
You can use kill() function to send any other signal to target processes, for example following will send SIGINT to a process IDs 104 and 102 −
#!/usr/bin/perl

kill('INT', 104, 102);
 
1;

Perl - Packages & Modules

What are Packages?

The package statement switches the current naming context to a specified namespace (symbol table). Thus −
  • A package is a collection of code which lives in its own namespace.
  • A namespace is a named collection of unique variable names (also called a symbol table).
  • Namespaces prevent variable name collisions between packages.
  • Packages enable the construction of modules which, when used, won't clobber variables and functions outside of the modules's own namespace.
  • The package stays in effect until either another package statement is invoked, or until the end of the current block or file.
  • You can explicitly refer to variables within a package using the ::package qualifier.
Following is an example having main and Foo packages in a file. Here special variable __PACKAGE__ has been used to print the package name.
#!/usr/bin/perl

# This is main package
$i = 1; 
print "Package name : " , __PACKAGE__ , " $i\n"; 

package Foo;
# This is Foo package
$i = 10; 
print "Package name : " , __PACKAGE__ , " $i\n"; 

package main;
# This is again main package
$i = 100; 
print "Package name : " , __PACKAGE__ , " $i\n"; 
print "Package name : " , __PACKAGE__ ,  " $Foo::i\n"; 

1;
When above code is executed, it produces the following result −
Package name : main 1
Package name : Foo 10
Package name : main 100
Package name : main 10

BEGIN and END Blocks

You may define any number of code blocks named BEGIN and END, which act as constructors and destructors respectively.
BEGIN { ... }
END { ... }
BEGIN { ... }
END { ... }
  • Every BEGIN block is executed after the perl script is loaded and compiled but before any other statement is executed.
  • Every END block is executed just before the perl interpreter exits.
  • The BEGIN and END blocks are particularly useful when creating Perl modules.
Following example shows its usage −
#!/usr/bin/perl

package Foo;
print "Begin and Block Demo\n";

BEGIN { 
    print "This is BEGIN Block\n" 
}

END { 
    print "This is END Block\n" 
}

1;
When above code is executed, it produces the following result −
This is BEGIN Block
Begin and Block Demo
This is END Block

What are Perl Modules?

A Perl module is a reusable package defined in a library file whose name is the same as the name of the package with a .pm as extension.
A Perl module file called Foo.pm might contain statements like this.
#!/usr/bin/perl

package Foo;
sub bar { 
   print "Hello $_[0]\n" 
}

sub blat { 
   print "World $_[0]\n" 
}
1;
Few important points about Perl modules
  • The functions require and use will load a module.
  • Both use the list of search paths in @INC to find the module.
  • Both functions require and use call the eval function to process the code.
  • The 1; at the bottom causes eval to evaluate to TRUE (and thus not fail).

The Require Function

A module can be loaded by calling the require function as follows −
#!/usr/bin/perl

require Foo;

Foo::bar( "a" );
Foo::blat( "b" );
You must have noticed that the subroutine names must be fully qualified to call them. It would be nice to enable the subroutine bar and blat to be imported into our own namespace so we wouldn't have to use the Foo:: qualifier.

The Use Function

A module can be loaded by calling the use function.
#!/usr/bin/perl

use Foo;

bar( "a" );
blat( "b" );
Notice that we didn't have to fully qualify the package's function names. Theuse function will export a list of symbols from a module given a few added statements inside a module.
require Exporter;
@ISA = qw(Exporter);
Then, provide a list of symbols (scalars, lists, hashes, subroutines, etc) by filling the list variable named @EXPORT: For Example −
package Module;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(bar blat);

sub bar { print "Hello $_[0]\n" }
sub blat { print "World $_[0]\n" }
sub splat { print "Not $_[0]\n" }  # Not exported!

1;

Create the Perl Module Tree

When you are ready to ship your Perl module, then there is standard way of creating a Perl Module Tree. This is done using h2xs utility. This utility comes alongwith Perl. Here is the syntax to use h2xs −
$h2xs -AX -n  ModuleName
For example, if your module is available in Person.pm file, then simply issue the following command −
$h2xs -AX -n Person
This will produce the following result −
Writing Person/lib/Person.pm
Writing Person/Makefile.PL
Writing Person/README
Writing Person/t/Person.t
Writing Person/Changes
Writing Person/MANIFEST
Here is the description of these options −
  • -A omits the Autoloader code (best used by modules that define a large number of infrequently used subroutines)
  • -X omits XS elements (eXternal Subroutine, where eXternal means external to Perl, i.e., C).
  • -n specifies the name of the module.
So above command creates the following structure inside Person directory. Actual result is shown above.
  • Changes
  • Makefile.PL
  • MANIFEST (contains the list of all files in the package)
  • README
  • t/ (test files)
  • lib/ ( Actual source code goes here
So finally, you tar this directory structure into a file Person.tar.gz and you can ship it. You will have to update README file with the proper instructions. You can also provide some test examples files in t directory.

Installing Perl Module

Download a Perl module in the form tar.gz file. Use the following sequence to install any Perl Module Person.pm which has been downloaded in asPerson.tar.gz file.
tar xvfz Person.tar.gz
cd Person
perl Makefile.PL
make
make install
The Perl interpreter has a list of directories in which it searches for modules (global array @INC).