📄 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>andModules</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 Modulesalthough you may not have realized it. I believe the shortestdefinition 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> moduleis 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 groupfuNCtions in units. 31 libraries shipped with Perl 4.036 Thesehave been replaced with a standard set of modules. However, theold libraries are still available in case you run across someold Perl scripts that need them.<P>Libraries-and modules-are generally placed in a subdirectory calledLib. On my machine, the library directory is <TT>c:\perl5\lib</TT>.If you don't know what your library directory is, ask your systemadministrator. 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 subdirectoryname, 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 theyaren't. The differeNCe is that compiler directives are carriedout when the script is compiled and fuNCtions are executed whilethe 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-withsome "module" stuff added. Modules should follow theseguidelines:<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 mainnamespace using the <TT>@EXPORT</TT>and <TT>@EXPORT_OK</TT> arrays ifobject-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 thoughtof as classes without constructors. Remember that the packagename <I>is</I> the class name. Whenever you see a package name,you're also seeing a class-even if none of the object-orientedtechniques are used.<P>Object-oriented modules keep all fuNCtion and variable names closeto the vest-so to speak. They are not available directly, youaccess them through the module name. Remember the <TT>Inventory_item->new()</TT>notation?<P>However, simple fuNCtion collections don't have this object-orientedneed for secrecy. They want your script to directly access thedefined fuNCtions. This is done using the Exporter class, <TT>@EXPORT</TT>,and <TT>@EXPORT_OK</TT>.<P>The <TT>Exporter</TT> class suppliesbasic fuNCtionality that gives your script access to the fuNCtionsand 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 namespaceand 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 nestedmodule. 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 nestedmodules.<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 discussionabout objects in the last chapter. Constructors are used to initializesomething and destructors are used to write log messages, closefiles, and do other clean-up type duties.<P>Perl has constructors and destructors that work at the modulelevel as well as the class level. The module constructor is calledthe <TT>BEGIN</TT> block, while themodule 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 evaluatedas soon as it is defined. Therefore, it can iNClude other fuNCtionsusing <TT>do()</TT> or <TT>require</TT>statements. SiNCe the blocks are evaluated immediately after definition,multiple <TT>BEGIN</TT> blocks willexecute in the order that they appear in the script.<P><IMG SRC="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>mainFoo</PRE></BLOCKQUOTE><H3><A NAME="TheTTFONTSIZEFACECourierENDFONTTTFONTSIZEBlockFONT">The <TT>END</TT>Block</FONT></A></H3><P>The <TT>END</TT> blocks are the lastthing 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 tolog files. Multiple <TT>END</TT> blocksare 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>FooMain<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" >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-hasits own symbol table. A <I>symbol table</I>, in Perl, is a hashthat holds all of the names defined in a namespace. All of thevariable and fuNCtion names can be found there. The hash for eachnamespace 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 entriesin the <TT>Foo::</TT> namespace.<P><IMG SRC="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 easierto read.<BR>Iterate over the symbols array displaying the key-value pairsof 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 Entriesin 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 + -