Perl Module

Summary: in this tutorial, you will learn about Perl module and how to develop a simple module in Perl.

Perl Module

A Perl module is a reusable collection of related variables and subroutines that perform a set of programming tasks. There are a lot of Perl modules available on the Comprehensive Perl Archive Network (CPAN). You can find various modules in a wide range of categories such as network, XML processing, CGI, database interfacing, etc.

To find a specific module for your project, check it out the CPAN Search section.

Perl module example

Suppose you are working on a project that requires logging functionality. You have done a research on CPAN but didn’t find any module that meets your requirements. You decided to create your own Perl module.

The first thing comes to your mind is the module name e.g., FileLogger. The main functionality of the FileLogger module is to:

  • Open the log file.
  • Write log messages to the log file based on log level.
  • Close the log file.

To create  FileLogger module, you need to do the following steps:

  1. First, create your own module name, in this case, you call it FileLogger.
  2. Second, create a file named modulename.pm. In this case, you need to create a new file named  FileLogger.pm. pm stands for Perl module.
  3. Third, make the FileLogger module a package by using the syntax:  package FileLogger; at the top of the  FileLogger.pm file.
  4. Fourth, write the code for subroutines and variables, and put the code into the  FileLogger.pm file.
  5. Fifth, put the last statement in the  FileLogger.pm file: 1; to make the file returns true.

Sound simple isn’t it? Let’s get started to develop the FileLogger module.

First, create a new file named  FileLogger.pm

Second, put the package name at the top of the  FileLogger.pm

package FileLogger;Code language: Perl (perl)

Third, put the global variable  $LEVEL so that any subroutine can access it.

my $LEVEL = 1;Code language: Perl (perl)

Fourth, develop subroutines to handle logging functionality. We need a subroutine to open the log file for writing log messages.

sub open{
   my $logfile = shift;
   # open log file for appending
   open(LFH, '>>', $logfile) or die "cannot open the log file $logfile: $!";
   # write time:
   print LFH "Time: ", scalar(localtime), "\n";
}Code language: Perl (perl)

We need another subroutine to append log messages to the log file. We only log messages if the input log level is lower than the current module’s log level. We use  print() function to write log messages into the log file.

sub log{
   my($log_level,$log_msg) = @_;

   if($log_level <= $LEVEL){
      print LFH "$log_msg\n";
   }
}Code language: Perl (perl)

We need a subroutine to close the log filehandle:

sub close{
   close LFH;
}Code language: Perl (perl)

We could allow other programs to change the log level  $LEVEL from the outside of the module. We can do this by creating a new subroutine set_level(). Inside the subroutine, we’ll check if the passed log level is a number using a regular expression before setting the module log level.

sub set_level{
   my $log_level = shift;

   if($log_level =~ /^\d+$/){
      $LEVEL = $log_level;
   }
}Code language: Perl (perl)

Fifth, at the end of the  FileLogger.pm file, we put the statement:  1;

Perl used to require a module to return a true value when using from other programs. The newer versions of Perl do not require the statement 1; at the end of the file anymore. However, we are putting the statement there just for backward compatibility.

Putting it all together.

package FileLogger;
# FileLogger.pm

use strict;
use warnings;

my $LEVEL = 1; # default log level

sub open{
   my $logfile = shift;
   # open log file for appending
   open(LFH, '>>', $logfile) or die "cannot open the log file $logfile: $!";
   # write logged time:
   print LFH "Time: ", scalar(localtime), "\n";
}

sub log{
   my($log_level,$log_msg) = @_;
   # append log if the passed log level is lower than
   # the module log level
   if($log_level <= $LEVEL){
      print LFH "$log_msg\n";
   }
}

sub close{
   close LFH;
}

sub set_level{
   # set the log level
   my $log_level = shift;
   # check if the passed log level is a number
   if($log_level =~ /^\d+$/){
      $LEVEL = $log_level;
   }
}

1;Code language: Perl (perl)

We’ve created the FileLogger module. How do we use it from other programs?

Using Perl Module

Perl provides three ways to use modules: do, require, and use.

  • do looks for the module file by searching the  @INC path. If Perl finds the file, it places the code inside the calling program and executes it. Otherwise, Perl will skip the do statement silently.
  • require loads the module file once. If you put the require with the same file twice, Perl will ignore it. In addition, Perl will issue an error message if it cannot find the file.
  • use is similar to require except that Perl applies it before the program starts. This is the reason why you cannot use the use statement with condition statements like if-else. You often use the use statement to include a module in your program.

Let’s write a program that uses the FileLogger module:

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

use FileLogger;

FileLogger::open("logtest.log");

FileLogger::log(1,"This is a test message");

FileLogger::close();Code language: Perl (perl)

We used the use statement to load the FileLogger module. Then we called the subroutines in the FileLogger module using syntax  module_name::subroutine_name e.g., FileLogger::openFileLogger::log and FileLogger::close. If you check the log file, you will see that log messages are there.

In this tutorial, we have shown you how to develop a simple Perl module called FileLogger and use it from other programs.

Was this tutorial helpful ?