Perl literacy course

Perl literacy course

lecture #7

Using modules and CPAN and a little about Pragmatic Modules

Shlomo Yona <yona@cs.technion.ac.il> http://yeda.cs.technion.ac.il/~yona/


do

do

do comes in three flavours:


do BLOCK
do SUBROUTINE(LIST)
do EXPR


do BLOCK

do BLOCK

Not really a function.

Returns the value of the last command in the sequence of commands indicated by BLOCK.

When modified by a loop modifier, executes the BLOCK once before testing the loop condition. (On other statements the loop modifiers test the conditional first.)

"do BLOCK" does not count as a loop, so the loop control statements "next", "last", or "redo" cannot be used to leave or restart the block.

(this usage of do does not import code)


do SUBROUTINE(LIST)

do SUBROUTINE(LIST)

A deprecated form of subroutine call.

(this usage of do does not import code either)


do EXPR

do EXPR

Uses the value of EXPR as a filename and executes the contents of the file as a Perl script.

Its primary use is to include subroutines from a Perl subroutine library.

(this is what we're after.)


Including code in Perl

Including code in Perl

Perl offers several different ways to include code from one file into another:


What is @INC

What is @INC

The array @INC contains the list of places that the "do EXPR", "require", or "use" constructs look for their library files.

It initially consists of the arguments to any -I command-line switches, followed by the default Perl library, followed by ".", to represent the current directory.


What is %INC

What is %INC

The hash %INC contains entries for each filename included via the "do", "require", or "use" operators.

The key is the filename you specified (with module names converted to pathnames), and the value is the location of the file found.

The "require" operator uses this hash to determine whether a particular file has already been included.


Including code in Perl -- do

Including code in Perl -- do


do $file;

is like


eval `cat $file`;

except the former

  1. is more efficient and concise
  2. searches @INC and updates %INC
  3. bequeaths an *unrelated* lexical scope on the eval'ed code (cannot see lexicals in the enclosing scope; "eval STRING" does.)

It's the same, however, in that it does reparse the file every time you call it, so you probably don't want to do this inside a loop.


Including code in Perl -- do (cont.)

Including code in Perl -- do

If "do" cannot read the file, it returns undef and sets $! to the error.

If "do" can read the file but cannot compile it, it returns undef and sets an error message in $@.

If the file is successfully compiled, "do" returns the value of the last expression evaluated.

You might like to use "do" to read in a program configuration file.

Manual error checking can be done this way:


# read in config files: system first, then user
for $file ("/share/prog/defaults.rc", "$ENV{HOME}/.someprogrc") {
	unless ($return = do $file) {
		warn "couldn't parse $file: $@" if $@;
		warn "couldn't do $file: $!"    unless defined $return;
		warn "couldn't run $file"       unless $return;
	}
}


require

require

require comes in two flavours:


require VERSION
require EXPR

Demands a version of Perl specified by VERSION, or demands some semantics specified by EXPR or by $_ if EXPR is not supplied.


require VERSION

require VERSION

VERSION may be either a numeric argument such as 5.006, which will be compared to $] (The version + patchlevel / 1000 of the Perl interpreter), or a literal of the form v5.6.1, which will be compared to $^V (aka $PERL_VERSION).

A fatal error is produced at run time if VERSION is greater than the version of the current Perl interpreter.

Specifying VERSION as a literal of the form v5.6.1 should generally be avoided, because it leads to misleading error messages under earlier versions of Perl which do not support this syntax.

The equivalent numeric version should be used instead.


require v5.6.1;     # run time version check
require 5.6.1;      # ditto
require 5.006_001;  # ditto; preferred for backwards compatibility

(this has nothing to do with icluding code)


require EXPR

require EXPR

require $file is like do $file, except the former

require Module is like require "Module.pm", except the former


require EXPR (cont.)

require EXPR

Demands that a library file be included if it hasn't already been included. The file is included via the do FILE mechanism, which is essentially just a variety of "eval".

Has semantics similar to the following subroutine:


sub require {
	my($filename) = @_;
	return 1 if $INC{$filename};
	my($realfilename,$result);
	ITER: {
		foreach $prefix (@INC) {
			$realfilename = "$prefix/$filename";
			if (-f $realfilename) {
				$INC{$filename} = $realfilename;
				$result = do $realfilename;
				last ITER;
			}
		}
		die "Can't find $filename in \@INC";
	}
	delete $INC{$filename} if $@ || !$result;
	die $@ if $@;
	die "$filename did not return true value" unless $result;
	return $result;
}

Note that the file will not be included twice under the same specified name.


require EXPR (cont.)

require EXPR

The file must return true as the last statement to indicate successful execution of any initialization code, so it's customary to end such a file with "1;" unless you're sure it'll return true otherwise.

But it's better just to put the "1;", in case you add more statements.


require EXPR (cont.)

require EXPR

If EXPR is a bareword, the require assumes a ".pm" extension and replaces "::" with "/" in the filename for you, to make it easy to load standard modules.

This form of loading of modules does not risk altering your namespace.

In other words, if you try this:


require Foo::Bar;    # a splendid bareword

The require function will actually look for the "Foo/Bar.pm" file in the directories specified in the @INC array.


require EXPR (cont.)

require EXPR

But if you try this:


	$class = 'Foo::Bar';
	require $class;      # $class is not a bareword
#or
	require "Foo::Bar";  # not a bareword because of the ""

The require function will look for the "Foo::Bar" file in the @INC array and will complain about not finding "Foo::Bar" there.


import

import

There is no builtin "import" function.

It is just an ordinary method (subroutine) defined (or inherited) by modules that wish to export names to another module.

The "use" function calls the "import" method for the package used.


use

use use has several flavours:


use Module VERSION LIST
use Module VERSION
use Module LIST
use Module
use VERSION


use (cont.)

use

use Module is like require Module, except the former


use (cont.)

use

Imports some semantics into the current package from the named module, generally by aliasing certain subroutine or variable names into your package. It is exactly equivalent to


BEGIN { require Module; import Module LIST; }

except that Module must be a bareword.

The "BEGIN" forces the "require" and "import" to happen at compile time.

The "require" makes sure the module is loaded into memory if it hasn't been yet.


use (cont.)

use

If you do not want to call the package's "import" method (for instance, to stop your namespace from being altered), explic- itly supply the empty list:


use Module ();

That is exactly equivalent to


BEGIN { require Module }


Using modules from the commanline

Using modules from the commanline


-m[-]module
-M[-]module
-M[-]'module ...'
-[mM][-]module=arg[,arg]...

-mmodule executes "use" module "();" before executing your program.

-Mmodule executes "use" module ";" before executing your program.

You can use quotes to add extra code after the module name, e.g., '-Mmodule qw(foo bar)'.


use and pragmas

use and pragmas

Because this is a wide-open interface, pragmas (compiler directives) are also implemented this way. Some of the currently implemented pragmas are (just as an example, we will discuss them later):


use constant;
use diagnostics;
use integer;
use sigtrap  qw(SEGV BUS);
use strict   qw(subs vars refs);
use subs     qw(afunc blurfl);
use warnings qw(all);
use sort     qw(stable _quicksort _mergesort);


Pragmatic Modules

Pragmatic Modules

They work somewhat like compiler directives (pragmata) in that they tend to affect the compilation of your program, and thus will usually work well only when used within a "use", or "no".

Most of these are lexically scoped, so an inner BLOCK may countermand them by saying:


no integer;
no strict 'refs';
no warnings;

which lasts until the end of that BLOCK.


Pragmatic Modules (cont.)

Pragmatic Modules

Some pragmas are lexically scoped--typically those that affect the $^H hints variable.

Others affect the current package instead, like "use vars" and "use subs", which allow you to predeclare a variables or subroutines within a particular file rather than just a block.

Such declarations are effective for the entire file for which they were declared.

You cannot rescind them with "no vars" or "no subs".


Pragmatic Modules -- what's available?

Pragmatic Modules -- what's available?

perldoc perlmodlib lists all of them, but let's mentioin some:


constant    Declare constants
diagnostics Perl compiler pragma to force verbose warning diagnostics
if          "use" a Perl module if a condition holds
integer     Use integer arithmetic instead of floating point
sort        Control sort() behaviour
strict      Restrict unsafe constructs
subs        Predeclare sub names
threads     Perl extension allowing use of interpreter based threads from perl
utf8        Enable/disable UTF-8 (or UTF-EBCDIC) in source code
vars        Predeclare global variable names (obsolete)
warnings    Control optional warnings


constant pragma

constant pragma

This will declare a symbol to be a constant with the given value.

This is a way for you to define immutable constants (meaning - things you cannot change).


constant pragma -- PI example

constant pragma -- PI example


use constant PI    => 4 * atan2(1, 1);
use constant DEBUG => 0;
print "Pi equals ", PI, "...\n" if DEBUG;

When you declare a constant such as "PI" using the method shown above, each machine your script runs upon can have as many digits of accuracy as it can use.

Also, your program will be easier to read, more likely to be maintained (and maintained correctly), and far less likely to send a space probe to the wrong planet because nobody noticed the one equation in which you wrote 3.14195.


constant pragma -- more examples

constant pragma -- more examples


use constant {
	SEC   => 0,
	MIN   => 1,
	HOUR  => 2,
	MDAY  => 3,
	MON   => 4,
	YEAR  => 5,
	WDAY  => 6,
	YDAY  => 7,
	ISDST => 8,
};

use constant WEEKDAYS => qw( Sunday Monday Tuesday Wednesday Thursday Friday Saturday);

print "Today is ", (WEEKDAYS)[ (localtime)[WDAY] ], ".\n";


constant pragma -- behaviour

constant pragma -- behaviour

When a constant is used in an expression, perl replaces it with its value at compile time, and may then optimize the expression further.

In particular, any code in an "if (CONSTANT)" block will be optimized away if the constant is false.


constant pragma -- example to a possible pitfall

constant pragma -- example to a possible pitfall

Constants defined using this module cannot be interpolated into strings like variables. However, concatenation works just fine:


print "Pi equals PI...\n";        # WRONG: does not expand "PI"
print "Pi equals ".PI."...\n";    # right


CPAN

CPAN

CPAN stands for Comprehensive Perl Archive Network, a ~700mb archive replicated on nearly 200 machines all over the world.

CPAN contains source code, non-native ports, documentation, scripts, and many third-party modules and extensions, designed for everything from commercial database interfaces to keyboard/screen control to web walking and CGI scripts.

The master web site for CPAN is www.cpan.org and there is the CPAN Multiplexer at www.cpan.org/CPAN.html which will choose a mirror near you via DNS.


CPAN -- a demonstration

CPAN -- a demonstration

CPAN http://www.cpan.org/

Search CPAN http://search.cpan.org/

Recent uploads to Search CPAN http://search.cpan.org/recent/


CPAN -- Installing

CPAN -- Installing

One way is to download the .tar.gz package and then 'tar zxvf' it, cd to the newly created directory tree, and then follow the instructions in the INSTALL file, which usually say:


% perl Makefile.PL
% make
% make test
% make install


CPAN -- Installing (cont.)

CPAN -- Installing

The other way is to use the CPAN module for browsing/searching, downloading and installing the module.

Interactive mode:


perl -MCPAN -e shell;

Batch mode:


use CPAN;
autobundle, clean, install, make, recompile, test

Of course, you'll need permissions for that...


CPAN -- Installing example

CPAN -- Installing example


% perl -MCPAN -e 'install Text::Soundex'


CPAN -- OK it's installed, now what?

CPAN -- OK it's installed, now what?

Every module, should have (and usually does) its documentation, which can be invoked using the perldoc system.


% perldoc Text::Soundex

and then you get a manpage which explains it all.


References

References

  1. Becoming a CPAN Tester with CPANPLUS by Autrijus Tang, http://www.perl.com/pub/a/2002/04/30/cpants.html
  2. CPAN FAQ at http://www.cpan.org/misc/cpan-faq.html
  3. CPAN http://www.cpan.org/
  4. CPAN PLUS by Jos Boumans, http://www.perl.com/pub/a/2002/03/26/cpanplus.html
  5. perldoc constant
  6. perldoc -f do
  7. perldoc -f import
  8. perldoc -f require
  9. perldoc -f use
  10. perldoc perlmod
  11. perldoc perlmodinstall
  12. perldoc perlmodlib
  13. perldoc perlmodlib
  14. perldoc perlrun [-Idirectory]
  15. perldoc perlrun [-M]
  16. perldoc perlvar [@INC and %INC]
  17. perldoc -q CPAN
  18. perldoc -q 'difference between require and use'
  19. The Lighter Side of CPAN by Alex Gough, http://www.perl.com/pub/a/2001/10/31/lighter.html


Thank you

Thank you