📄 ch4.htm
字号:
The default use of a variable name defers to the current package
active at the time of compilation. Thus, if you are in the package
<TT><FONT FACE="Courier">Finance.pm</FONT></TT> and specify a
variable <TT><FONT FACE="Courier">$pv</FONT></TT>, the variable
is actually equal to <TT><FONT FACE="Courier">$Finance::$pv</FONT></TT>.
<H2><A NAME="UsingPerlModulesusevsrequire"><FONT SIZE=5 COLOR=#FF0000>Using
Perl Modules: </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">use</FONT></TT><FONT SIZE=5 COLOR=#FF0000>
vs. </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">require</FONT></TT></A>
</H2>
<P>
You include Perl modules in your program by using the <TT><FONT FACE="Courier">use</FONT></TT>
or the <TT><FONT FACE="Courier">require</FONT></TT> statement.
Here's the way to use either of these statements:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">use ModuleName;<BR>
</FONT></TT>require ModuleName;
</BLOCKQUOTE>
<P>
Note that the <TT><FONT FACE="Courier">.pm</FONT></TT> extension
is not used in the code shown above. Also note that neither statement
allows a file to be included more than once in a program. The
returned value of true (<TT><FONT FACE="Courier">1;</FONT></TT>)
as the last statement is required to let Perl know that a <TT><FONT FACE="Courier">require</FONT></TT>d
or <TT><FONT FACE="Courier">use</FONT></TT>d module loaded correctly
and lets the Perl interpreter ignore any reloads. In general,
it's better to use the <TT><FONT FACE="Courier">use Module;</FONT></TT>
statement than the <TT><FONT FACE="Courier">require Module;</FONT></TT>
statement in a Perl program to remain compatible with future versions
of Perl.
<P>
For modules, you might want to consider continuing to use the
<TT><FONT FACE="Courier">require</FONT></TT> statement. Here's
why: The <TT><FONT FACE="Courier">use</FONT></TT> statement does
a little bit more work than the <TT><FONT FACE="Courier">require</FONT></TT>
statement in that it alters the namespace of the module that includes
another module. You want this extra update of the namespace to
be done in a program. However, when writing code for a module,
you may not want the namespace to be altered unless it's explicitly
required. In this event, you will use the <TT><FONT FACE="Courier">require</FONT></TT>
statement.
<P>
The <TT><FONT FACE="Courier">require</FONT></TT> statement includes
the full pathname of a file in the <TT><FONT FACE="Courier">@Inc</FONT></TT>
array so that the functions and variables in the module's file
are in a known location during execution time. Therefore, the
functions that are imported from a module are imported via an
explicit module reference at runtime with the <TT><FONT FACE="Courier">require</FONT></TT>
statement. The <TT><FONT FACE="Courier">use</FONT></TT> statement
does the same thing as the <TT><FONT FACE="Courier">require</FONT></TT>
statement because it updates the <TT><FONT FACE="Courier">@Inc</FONT></TT>
array with full pathnames of loaded modules. The code for the
<TT><FONT FACE="Courier">use</FONT></TT> function also goes a
step further and calls an <TT><FONT FACE="Courier">import</FONT></TT>
function in the module being <TT><FONT FACE="Courier">use</FONT></TT>d
to explicitly load the list of exported functions at compile time,
thus saving the time required for an explicit resolution of a
function name during execution.
<P>
Basically, the <TT><FONT FACE="Courier">use</FONT></TT> statement
is equivalent to
<BLOCKQUOTE>
<TT><FONT FACE="Courier">require ModuleName; import ModuleName
[list of imported functions];</FONT></TT>
</BLOCKQUOTE>
<P>
The use of the <TT><FONT FACE="Courier">use</FONT></TT> statement
does change your program's namespace because the imported function
names are inserted in the symbol table. The <TT><FONT FACE="Courier">require</FONT></TT>
statement does not alter your program's namespace. Therefore,
the following statement
<BLOCKQUOTE>
<TT><FONT FACE="Courier">use ModuleName (); </FONT></TT>
</BLOCKQUOTE>
<P>
is equivalent to this statement:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">require ModuleName;</FONT></TT>
</BLOCKQUOTE>
<P>
Functions are imported from a module via a call to a function
called <TT><FONT FACE="Courier">import</FONT></TT>. You can write
your own <TT><FONT FACE="Courier">import</FONT></TT> function
in a module, or you can use the <TT><FONT FACE="Courier">Exporter</FONT></TT>
module and use its <TT><FONT FACE="Courier">import</FONT></TT>
function. In almost all cases, you will use the <TT><FONT FACE="Courier">Exporter</FONT></TT>
module to provide an <TT><FONT FACE="Courier">import</FONT></TT>
function instead of reinventing the wheel. (You'll learn more
on this in the next section.) Should you decide not to use the
<TT><FONT FACE="Courier">Exporter</FONT></TT> module, you will
have to write your own <TT><FONT FACE="Courier">import</FONT></TT>
function in each module that you write. It's much easier to simply
use the <TT><FONT FACE="Courier">Exporter</FONT></TT> module and
let Perl do the work for you.
<H2><A NAME="TheSampleLetterpmModule"><FONT SIZE=5 COLOR=#FF0000>The
Sample </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">Letter.pm</FONT></TT><FONT SIZE=5 COLOR=#FF0000>
Module</FONT></A></H2>
<P>
The best way to illustrate the semantics of how a module is used
in Perl is to write a simple module and show how to use it. Let's
take the example of a local loan shark, Rudious Maximus, who is
simply tired of typing the same "request for payment"
letters. Being an avid fan of computers and Perl, Rudious takes
the lazy programmer's approach and writes a Perl module to help
him generate his memos and letters.
<P>
Now, instead of typing within fields in a memo template file,
all he has to do is type a few lines to produce his nice, threatening
note. Listing 4.1 shows you what he has to type.
<HR>
<BLOCKQUOTE>
<B>Listing 4.1. Using the </B><TT><B><FONT FACE="Courier">Letter</FONT></B></TT><B>
module.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl -w<BR>
2 #<BR>
3 # Uncomment the line
below to include the current dir in @Inc.<BR>
4 # push (@Inc, 'pwd');<BR>
5 #<BR>
6 use Letter;<BR>
7 <BR>
8 Letter::To("Mr. Gambling Man","The money
for Lucky Dog, Race 2");<BR>
9 Letter::ClaimMoneyNice();
<BR>
10 Letter::ThankDem();<BR>
11 Letter::Finish();</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">use Letter;</FONT></TT> statement
is present to force the Perl interpreter to include the code for
the module in the application program. The module should be located
in the <TT><FONT FACE="Courier">/usr/lib/perl5/</FONT></TT> directory,
or you can place it in any directory listed in the <TT><FONT FACE="Courier">@Inc</FONT></TT>
array. The <TT><FONT FACE="Courier">@Inc</FONT></TT> array is
the list of directories that the Perl interpreter will look for
when attempting to load the code for the named module. The commented
line (number 4) shows how to add the current working directory
to include the path. The next four lines in the file generate
the subject matter for the letter.
<P>
Here's the output from using the <TT><FONT FACE="Courier">Letter</FONT></TT>
module:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">To: Mr. Gambling Man<BR>
Fm: Rudious Maximus, Loan Shark<BR>
Dt: Wed Feb 7 10:35:51 CST 1996<BR>
<BR>
Re: The money for Lucky Dog, Race 2<BR>
<BR>
<BR>
====================================================<BR>
<BR>
It has come to my attention that your account is<BR>
way over due.<BR>
You gonna pay us soon?<BR>
Or would you like me to come ovah?<BR>
<BR>
Thanks for your support.<BR>
<BR>
<BR>
<BR>
Sincerely,<BR>
Rudious</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">Letter</FONT></TT> module file is
shown in Listing 4.2. The name of the package is declared in the
first line. Because this module's functions will be exported,
I use the <TT><FONT FACE="Courier">Exporter</FONT></TT> module.
Therefore, the statement <TT><FONT FACE="Courier">use Exporter;</FONT></TT>
is required to inherit functionality from the <TT><FONT FACE="Courier">Exporter</FONT></TT>
module. Another required step is putting the word <TT><FONT FACE="Courier">Exported</FONT></TT>
in the <TT><FONT FACE="Courier">@ISA</FONT></TT> array to allow
searching for <TT><FONT FACE="Courier">Exported.pm</FONT></TT>.
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD ><B>Note</B></TD></TR>
<TR VALIGN=TOP><TD >
<BLOCKQUOTE>
The <TT><FONT FACE="Courier">@ISA</FONT></TT> array is a special array within each package. Each item in the array lists where else to look for a method if it cannot be found in the current package. The order in which packages are listed in the <TT><FONT
FACE="Courier">@ISA</FONT></TT> array is the order in which Perl searches for unresolved symbols. A class that is listed in the <TT><FONT FACE="Courier">@ISA</FONT></TT> array is referred to as the base class of that particular class. Perl will cache
missing methods found in base classes for future references. Modifying the <TT><FONT FACE="Courier">@ISA</FONT></TT> array will flush the cache and cause Perl to look up all methods again.
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
Let's now look at the code for <TT><FONT FACE="Courier">Letter.pm</FONT></TT>
in Listing 4.2.
<HR>
<BLOCKQUOTE>
<B>Listing 4.2. The </B><TT><B><FONT FACE="Courier">Letter.pm</FONT></B></TT><B>
module.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 package Letter;<BR>
2 <BR>
3 require Exporter;
<BR>
4 @ISA = (Exporter);<BR>
5 <BR>
6 =head1 NAME<BR>
7 <BR>
8 Letter - Sample module to generate letterhead for you
<BR>
9 <BR>
10 =head1 SYNOPSIS<BR>
11 <BR>
12 use Letter;<BR>
13 <BR>
14 Letter::Date();<BR>
15 Letter::To($name,$company,$address);
<BR>
16 <BR>
17 Then one of the following:<BR>
18 Letter::ClaimMoneyNice() {
<BR>
19 Letter::ClaimMoney();<BR>
20 Letter::ThreatBreakLeg();<BR>
21 <BR>
22 Letter::ThankDem();<BR>
23 Letter::Finish();<BR>
24 <BR>
25 =head1 DESCRIPTION<BR>
26 <BR>
27 This module provides a short example of generating a letter
for a<BR>
28 friendly neighborbood loan shark.<BR>
29 <BR>
30 The code begins after the "cut" statement.<BR>
31 =cut<BR>
32 <BR>
33 @EXPORT = qw( Date,<BR>
34
To,<BR>
35
ClaimMoney,<BR>
36
ClaimMoneyNice,<BR>
37
ThankDem,<BR>
38
Finish );<BR>
39 <BR>
40 #<BR>
41 # Print today's date<BR>
42 #<BR>
43 sub Letter::Date {<BR>
44
$date = 'date';<BR>
45
print "\n Today is $date";<BR>
46 }<BR>
47 <BR>
48 sub Letter::To {<BR>
49
local($name) = shift;<BR>
50
local($subject) = shift;<BR>
51
print "\n To: $name";<BR>
52
print "\n Fm: Rudious Maximus, Loan Shark";<BR>
53
print "\n Dt: ", `date`;<BR>
54
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -