📄 ch15.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 15 -- Perl Modules</TITLE>
<META>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT SIZE=6 COLOR=#FF0000>Chapter 15</FONT></H1>
<H1><FONT SIZE=6 COLOR=#FF0000>Perl Modules</FONT></H1>
<HR>
<P>
<CENTER><B><FONT SIZE=5>CONTENTS</FONT></B></CENTER>
<UL>
<LI><A HREF="#ModuleConstructorsandDestructors">
Module Constructors and Destructors</A>
<UL>
<LI><A HREF="#TheTTFONTSIZEFACECourierBEGINFONTTTFONTSIZEBlockFONT">
The <TT>BEGIN </TT>Block</FONT>
</A>
<LI><A HREF="#TheTTFONTSIZEFACECourierENDFONTTTFONTSIZEBlockFONT">
The <TT>END</TT>
Block</FONT></A>
</UL>
<LI><A HREF="#SymbolTables">
Symbol Tables</A>
<LI><A HREF="#TheTTFONTSIZEFACECourierrequireFONTTTFONTSIZECompilerDirectiveFONT">
The <TT>require</TT>
Compiler Directive</FONT></A>
<LI><A HREF="#TheTTFONTSIZEFACECourieruseFONTTTFONTSIZECompilerDirectiveFONT">
The <TT>use</TT>
Compiler Directive</FONT></A>
<LI><A HREF="#WhatsaPragma">
What's a Pragma?</A>
<LI><A HREF="#TheTTFONTSIZEFACECourierstrictFONTTTFONTSIZEPragmaFONT">
The <TT>strict</TT>
Pragma</FONT></A>
<LI><A HREF="#TheStandardModules">
The Standard Modules</A>
<LI><A HREF="#TTFONTSIZEFACECourierstrictmyFONTTTFONTSIZEandModulesFONT">
<TT>strict, my() </TT>and
Modules</FONT></A>
<LI><A HREF="#ModuleExamples">
Module Examples</A>
<UL>
<LI><A HREF="#ExampleTheTTFONTSIZEFACECourierCarpFONTTTFONTSIZEModuleFONT">
Example: The <TT>Carp</TT>
Module</FONT></A>
<LI><A HREF="#ExampleTheTTFONTSIZEFACECourierEnglishFONTTTFONTSIZEModuleFONT">
Example: The <TT>English</TT>
Module</FONT></A>
<LI><A HREF="#ExampleTheTTFONTSIZEFACECourierEnvFONTTTFONTSIZEModuleFONT">
Example: The <TT>Env </TT>Module</FONT>
</A>
</UL>
<LI><A HREF="#Summary">
Summary</A>
<LI><A HREF="#ReviewQuestions">
Review Questions</A>
<LI><A HREF="#ReviewExercises">
Review Exercises</A>
</UL>
<HR>
<P>
In the last chapter, you were introduced to object-oriented programming.
Along the way, you learned some aspects of programming with Modules
although you may not have realized it. I believe the shortest
definition of a <I>module</I> is a namespace defined in a file.
For example, the <TT>English</TT>
module is defined in the <TT>English.pm</TT>
file and the <TT>Find</TT> module
is defined in the <TT>Find.pm</TT>
file.
<P>
Of course, modules are more than simply a namespace in a file.
But, don't be coNCerned-there's not much more.
<P>
Perl 4, the last version of Perl, depended on libraries to group
fuNCtions in units. 31 libraries shipped with Perl 4.036 These
have been replaced with a standard set of modules. However, the
old libraries are still available in case you run across some
old Perl scripts that need them.
<P>
Libraries-and modules-are generally placed in a subdirectory called
Lib. On my machine, the library directory is <TT>c:\perl5\lib</TT>.
If you don't know what your library directory is, ask your system
administrator. Some modules are placed in subdirectories like
<TT>Lib/Net</TT> or <TT>Lib/File</TT>.
The modules in these subdirectories are loaded using the subdirectory
name, two colons, and the module name. For example, <TT>Net::Ping</TT>
or <TT>File::Basename</TT>.
<P>
Libraries are made available to your script by using the <TT>require</TT>
compiler directive. Directives may seem like fuNCtions, but they
aren't. The differeNCe is that compiler directives are carried
out when the script is compiled and fuNCtions are executed while
the script is running.<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
You might think the distiNCtion between compiler directives and fuNCtions is minor. And you might be right. I like to be as precise as possible when using computer terminology. After all, the computer is precise; why shouldn't we be, too?</BLOCKQUOTE>
<BLOCKQUOTE>
Unfortunately, Perl doesn't make it easy to create simple definitions and place every feature into a nice orderly category. So don't get hung up on attaching a label to everything. If you know what something does, the names won't matter a whole
lot.</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
Some modules are just collections of fuNCtions-like the libraries-with
some "module" stuff added. Modules should follow these
guidelines:
<UL>
<LI>The file name should be the same as the package name.
<LI>The package name should start with a capital letter.
<LI>The file name should have a file extension of <TT>pm</TT>.
<LI>The package should be derived from the <TT>Exporter</TT>
class if object-oriented techniques are not being used.
<LI>The module should export fuNCtions and variables to the main
namespace using the <TT>@EXPORT</TT>
and <TT>@EXPORT_OK</TT> arrays if
object-oriented techniques are not being used.
</UL>
<P>
Modules are loaded by the <TT>use</TT>
directive, which is similar to <TT>require</TT>
except it automates the importing of fuNCtion and variable names.
<P>
Modules that are simply a collection of fuNCtions can be thought
of as classes without constructors. Remember that the package
name <I>is</I> the class name. Whenever you see a package name,
you're also seeing a class-even if none of the object-oriented
techniques are used.
<P>
Object-oriented modules keep all fuNCtion and variable names close
to the vest-so to speak. They are not available directly, you
access them through the module name. Remember the <TT>Inventory_item->new()</TT>
notation?
<P>
However, simple fuNCtion collections don't have this object-oriented
need for secrecy. They want your script to directly access the
defined fuNCtions. This is done using the Exporter class, <TT>@EXPORT</TT>,
and <TT>@EXPORT_OK</TT>.
<P>
The <TT>Exporter</TT> class supplies
basic fuNCtionality that gives your script access to the fuNCtions
and variables inside the module. The <TT>import()</TT>
fuNCtion, defined inside the <TT>Exporter</TT>
class, is executed at compile-time by the <TT>use</TT>
compiler directive. The <TT>import()</TT>
fuNCtion takes fuNCtion and variable names from the module namespace
and places them into the <TT>main</TT>
namespace. Thus, your script can access them directly.<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
I can almost hear your thoughts at this point. You're thinking, "The exporting of fuNCtion and variable names is handled by the <TT><I>import() </I></TT>fuNCtion?" Well, I sympathize. But, look at it this way: The module is exporting and your
script is importing.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
You may occasionally see a refereNCe to what may look like a nested
module. For example, <TT>$Outer::Inner::foo</TT>.
This really refers to a module named <TT>Outer::Inner</TT>,
so named by the statement: <TT>package Outer::Inner;</TT>.
Module designers sometimes use this technique to simulate nested
modules.
<H2><A NAME="ModuleConstructorsandDestructors"><FONT SIZE=5 COLOR=#FF0000>
Module Constructors and Destructors</FONT></A></H2>
<P>
You may recall constructors and destructors from the discussion
about objects in the last chapter. Constructors are used to initialize
something and destructors are used to write log messages, close
files, and do other clean-up type duties.
<P>
Perl has constructors and destructors that work at the module
level as well as the class level. The module constructor is called
the <TT>BEGIN</TT> block, while the
module destructor is called the <TT>END</TT>
block.
<H3><A NAME="TheTTFONTSIZEFACECourierBEGINFONTTTFONTSIZEBlockFONT">
The <TT>BEGIN </TT>Block</FONT>
</A></H3>
<P>
The <TT>BEGIN</TT> block is evaluated
as soon as it is defined. Therefore, it can iNClude other fuNCtions
using <TT>do()</TT> or <TT>require</TT>
statements. SiNCe the blocks are evaluated immediately after definition,
multiple <TT>BEGIN</TT> blocks will
execute in the order that they appear in the script.
<P>
<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>
<BLOCKQUOTE>
<I>Define a </I><TT><I>BEGIN</I></TT><I>
block for the main package.<BR>
Display a string indicating the begin block is executing.<BR>
Start the </I><TT><I>Foo</I></TT><I>
package.<BR>
Define a </I><TT><I>BEGIN</I></TT><I>
block for the </I><TT><I>Foo</I></TT><I>
package.<BR>
Display a string indicating the begin block is executing.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 15.1 15LST01.PL-Using </B><TT><B><FONT FACE="Courier">BEGIN</FONT></B></TT><B>
Blocks<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
BEGIN {
print("main\n");
}
package Foo;
BEGIN {
print("Foo\n");
}
</PRE>
</BLOCKQUOTE>
<HR>
<P>
This program displays:
<BLOCKQUOTE>
<PRE>
main
Foo
</PRE>
</BLOCKQUOTE>
<H3><A NAME="TheTTFONTSIZEFACECourierENDFONTTTFONTSIZEBlockFONT">
The <TT>END</TT>
Block</FONT></A></H3>
<P>
The <TT>END</TT> blocks are the last
thing to be evaluated. They are even evaluated after <TT>exit()</TT>
or <TT>die()</TT> fuNCtions are called.
Therefore, they can be used to close files or write messages to
log files. Multiple <TT>END</TT> blocks
are evaluated in reverse order.
<HR>
<BLOCKQUOTE>
<B>Listing 15.2 15LST02.PL-Using </B><TT><B><FONT FACE="Courier">END</FONT></B></TT><B>
Blocks<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
END {
print("main\n");
}
package Foo;
END {
print("Foo\n");
}
</PRE>
</BLOCKQUOTE>
<HR>
<P>
This program displays:
<BLOCKQUOTE>
<PRE>
Foo
Main<BR>
</PRE>
</BLOCKQUOTE>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
Signals that are sent to your script can bypass the <TT>END</TT> blocks. So, if your script is in danger of stopping due to a signal, be sure to define a signal-handler fuNCtion. See <A HREF="ch13.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch13.htm" >Chapter 13</A>, "Handling Errors and
Signals," for more information.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<H2><A NAME="SymbolTables"><FONT SIZE=5 COLOR=#FF0000>
Symbol Tables</FONT></A></H2>
<P>
Each namespace-and therefore, each module, class, or package-has
its own symbol table. A <I>symbol table</I>, in Perl, is a hash
that holds all of the names defined in a namespace. All of the
variable and fuNCtion names can be found there. The hash for each
namespace is named after the namespace with two colons. For example,
the symbol table for the <TT>Foo</TT>
namespace is called <TT>%Foo::</TT>.
Listing 15.3 shows a program that displays all of the entries
in the <TT>Foo::</TT> namespace.
<P>
<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>
<BLOCKQUOTE>
<I>Define the </I><TT><I>dispSymbols()</I></TT><I>
fuNCtion.<BR>
Get the hash refereNCe that should be the first parameter.<BR>
Declare local temporary variables.<BR>
Initialize the </I><TT><I>%symbols</I></TT><I>
variable. This is done to make the code easier to read.<BR>
Initialize the </I><TT><I>@symbols</I></TT><I>
variables. This variable is also used to make the code easier
to read.<BR>
Iterate over the symbols array displaying the key-value pairs
of the symbol table.<BR>
Call the </I><TT><I>dispSymbols()</I></TT><I>
fuNCtion to display the symbols for the Foo package.<BR>
Start the Foo package.<BR>
Initialize the </I><TT><I>$bar</I></TT><I>
variable. This will place an entry into the symbol table.<BR>
Define the </I><TT><I>baz()</I></TT><I>
fuNCtion. This will also create an entry into the symbol table.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 15.3 15LST03.PL-How to Display the Entries
in a Symbol Table<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
sub dispSymbols {
my($hashRef) = shift;
my(%symbols);
my(@symbols);
%symbols = %{$hashRef};
@symbols = sort(keys(%symbols));
foreach (@symbols) {
printf("%-10.10s| %s\n", $_, $symbols{$_});
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -