⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch15.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<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&nbsp;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 &quot;module&quot; 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-&gt;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, &quot;The exporting of fuNCtion and variable names is handled by the <TT><I>import() </I></TT>fuNCtion?&quot; 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&nbsp;&nbsp;15LST01.PL-Using </B><TT><B><FONT FACE="Courier">BEGIN</FONT></B></TT><B>

Blocks<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

BEGIN {

    print(&quot;main\n&quot;);

}



package Foo;

    BEGIN {

        print(&quot;Foo\n&quot;);

    }

</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&nbsp;&nbsp;15LST02.PL-Using </B><TT><B><FONT FACE="Courier">END</FONT></B></TT><B>

Blocks<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

END {

    print(&quot;main\n&quot;);

}



package Foo;

    END {

        print(&quot;Foo\n&quot;);

    }

</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>, &quot;Handling Errors and 
Signals,&quot; 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&nbsp;&nbsp;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(&quot;%-10.10s| %s\n&quot;, $_, $symbols{$_});

    }

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -