הלינקייה: מגזין חודשי למפתחים

רוצה לשמוע על כל האירועים, המדריכים, הקורסים והמאמרים שנכתבו החודש ?
הלינקייה הינו מגזין חופשי בעברית שמשאיר אותך בעניינים.
בלי ספאם. בלי שטויות. פעם בחודש אצלך בתיבה.

Modules

Standard Perl Modules

Custom Perl Modules

In perl, a module is a collection of subroutines wrapped up in a single namespace (called a package). The module is a basic unit of code reuse, for it allows us to use code of other developers without diving into the gory details of the code.
A module is simply a collection of subroutines in a perl file, with the extension "pm", and the last line of the module must return a true value.

When writing a module, the following guidelines are strongly advised:

  • The module should have a single package, at the beginning of the module.
  • The module last line of code should end with 1; to make sure a true value is returned.
  • perldoc style documentation is to be placed at the end of the module, after all code ends
  • Unit tests for the module should reside in .t files

Module Search Path

perl maintains a list of search paths for modules in the @INC package variable. That variable is built at runtime from the default search path and the environment variable PERL5LIB.

To view the list, you can use:

perl -e '{$,="\n"; print @INC}'

It is recommended user defined or organization specific modules should be placed in a local path. Adding a custom path to the search path is performed by either changing the PERL5LIB environment variable (from outside the perl code), or by modifying @INC from inside the perl code (either directly or by use lib).
The following code uses a custom path to load modules from:

use lib '/opt/local/perl-modules/';
# this will look for a file:
# My/Custom/Module.pm
# under each path in the search path, including the new lib added earlier.
use My::Custom::Module;

Module Example

Here's a complete example for a module along with embedded perldoc.

package Calc;
use Modern::Perl;
 
sub plus {
	my ($a, $b) = @_;
	return $a+$b;
}
 
sub minus {
	my ($a, $b) = @_;
	return $a-$b;
}
 
1;

=head1 Simple Calculator Module
 
The calculator module provides functionality related to calculating 
and doing math. 
It supports all basic operations.

=over
 
=item plus()
 
The plus subroutine takes two numbers and returns their sum

=item minus()
 
The minus subroutine takes two numbers and returns the first minus the second

=back

Thank you for choosing the Calculator module.

package Calc;
 
use Calc;
use Modern::Perl;
  
my @registers;

sub add_to_register {
	my ($reg, @values) = @_;
	$registers[$reg] += $_ for (@values);
}

sub read_register {
	my $reg = shift;
	return $registers[$reg] || 0;
}

1;
 
=head1 Improved Calculator Module
 
The improved calculator adds 10 memory registers to our old calculator module. Using those registers, we can run all sorts of complicated calculations. 
The registers are stored in a lexically scoped list for this module

=over
 
=item add_to_register(register_id, values) 
 
This function takes a register id and a list of values, and adds those values
to a given register

=item read_register(register_id)
 
The read_register operation returns the current value of a register.

=back
 
use Modern::Perl;
use ImprovedCalc;
 
Calc::plus(10, 20);
Calc::add_to_register(1, 5, 10, 15, 20);
 
print "*** Register values:\n";
print "$_ => ", Calc::read_register($_), "\n" for (1..10);
use Test::More tests => 5;
use Calc;
 
is( Calc::plus(1,1), 2, "one plus one");
is( Calc::minus(3, 2), 1, "positive minus");
is( Calc::minus(0, 2), -2, "negative minus");
 
ok( Calc::plus(2, 2) == 4, "ok positive plus");
ok( Calc::minus(3, 5) == -1, "ok negative minus");
 
package Foo;
use base 'Exporter';
 
# sub bar and baz will be exporter
# by anyone writing: use Foo
 
our @EXPORT    = qw(bar baz);
 
# writing: use Foo qw(bar hello) will
# import bar and hello into the main 
# symbol table when using this module
our @EXPORT_OK = qw(bar baz hello);
 
sub bar {
  warn 'In Bar';
}
 
sub baz {
  warn 'In Baz';
}
 
sub hello {
  warn 'In Hello';
}
 
use Carp; 
use strict; 
 
foo(); 
 
sub foo { 
	bar(); 
} 
 
sub bar { 
	baz(); 
} 
 
sub baz { 
	confess("I give up!"); 
}
 

 
package Regexp;
use strict;
use warnings;
use Carp;
 
use base 'Exporter';
our @EXPORT = qw(%REGEXPS);
 
 
my $PHONE_NUMBER_RE = qr {
# A phone number is a 7 digit number
# It has 2 or 3 digits prefix
# Then a dash (maybe)
# And 7 more digits without leading zeros
# For Example:
#
# 054-2040681
# 0522311894
# 09-9441020
 
# start
    ^
# prefix
    (?: \d{2} | \d{3} )
 
# maybe dash
    -?
 
# 7 more digits (no leading zeros and ones)
    [2-9]\d{6}
 
# end
    $
}xms;
 
 
 
our %REGEXPS = (
    PHONE   =>   $PHONE_NUMBER_RE,
);
 
1;
course: