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

📄 ch4.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<HTML>



<HEAD>

   <TITLE>Chapter 4 -- Introduction to Perl Modules</TITLE>

   <META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">

</HEAD>

<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">

<H1><FONT COLOR=#FF0000>Chapter 4</FONT></H1>

<H1><B><FONT SIZE=5 COLOR=#FF0000>Introduction to Perl Modules</FONT></B>

</H1>

<P>

<HR WIDTH="100%"></P>

<P>

<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>

</FONT></FONT></H3>



<UL>

<LI><A HREF="#WhatIsaPerlModule" >What Is a Perl Module?</A>

<LI><A HREF="#UsingPerlModulesusevsrequire" >Using Perl Modules: use vs. require</A>

<LI><A HREF="#TheSampleLetterpmModule" >The Sample Letter.pm Module</A>

<LI><A HREF="#SubroutinesandPassingParameters" >Subroutines and Passing Parameters</A>

<LI><A HREF="#AnotherSampleModuleFinance" >Another Sample Module: Finance</A>

<UL>

<LI><A HREF="#ReturnedValuesfromSubroutinesinaPa" >Returned Values from Subroutines in a Package</A>

</UL>

<LI><A HREF="#MultipleInheritance" >Multiple Inheritance</A>

<LI><A HREF="#ThePerlModuleLibraries" >The Perl Module Libraries</A>

<UL>

<LI><A HREF="#ExtensionModules" >Extension Modules</A>

<LI><A HREF="#WhatIsCPAN" >What Is CPAN?</A>

</UL>

<LI><A HREF="#Summary" >Summary</A>

</UL>

<HR>

<P>

This chapter introduces you to the concepts behind references

to Perl modules, packages, and classes. It also shows you how

to create a few sample modules.

<H2><A NAME="WhatIsaPerlModule"><FONT SIZE=5 COLOR=#FF0000>What

Is a Perl Module?</FONT></A></H2>

<P>

A Perl module is a set of Perl code that acts like a library of

function calls. The term <I>module</I> in Perl is synonymous with

the word <I>package</I>. Packages are a feature of Perl 4, whereas

modules are prevalent in Perl 5. 

<P>

You can keep all your reusable Perl code specific to a set of

tasks in a Perl module. Therefore, all the functionality pertaining

to one type of task is contained in one file. It's easier to build

an application on these modular blocks. Hence, the word <I>module</I>

applies a bit more than <I>package</I>.

<P>

Here's a quick introduction to modules. Certain topics in this

section will be covered in detail throughout the rest of the book.

Read the following paragraphs carefully to get an overview of

what lies ahead as you write and use your own modules.

<P>

What is confusing is that the terms <I>module</I> and <I>package</I>

are used interchangeably in all Perl documentation, and <I>these

two terms mean the very same thing</I>. So when reading Perl documents,

just think &quot;package&quot; when you see &quot;module&quot;

and vice versa.

<P>

So, what's the premise for using modules? Well, modules are there

to package (pardon the pun) variables, symbols, and interconnected

data items together. For example, using global variables with

very common names such as <TT><FONT FACE="Courier">$k</FONT></TT>,

<TT><FONT FACE="Courier">$j</FONT></TT>, or <TT><FONT FACE="Courier">$i</FONT></TT>

in a program is generally not a good idea. Also, a loop counter,

<TT><FONT FACE="Courier">$i</FONT></TT>, should be allowed to

work independently in two different portions of the code. Declaring

<TT><FONT FACE="Courier">$i</FONT></TT> as a global variable and

then incrementing it from within a subroutine will create unmanageable

problems with your application code because the subroutine may

have been called from within a loop that also uses a variable

called <TT><FONT FACE="Courier">$i</FONT></TT>. The use of modules

in Perl allows variables with the same name to be created at different,

distinct places in the same program. 

<P>

The symbols defined for your variables are stored in an associative

array, referred to as a <I>symbol table</I>. These symbol tables

are unique to a package. Therefore, variables of the same name

in two different packages can have different values. 

<P>

Each module has its own symbol table of all symbols that are declared

within it. The symbol table basically isolates synonymous names

in one module from another. The symbol table defines a <I>namespace</I>,

that is, a space for independent variable names to exist in. Thus,

the use of modules, each with its own symbol table, prevents a

variable declared in one section from overwriting the values of

other variables with the same name declared elsewhere in the same

program.

<P>

As a matter of fact, all variables in Perl belong to a package.

The variables in a Perl program belong to the <TT><FONT FACE="Courier">main</FONT></TT>

package. All other packages within a Perl program either are nested

within this main package or exist at the same level. There are

some truly global variables, such as the signal handler array

<TT><FONT FACE="Courier">%SIG</FONT></TT>, that are available

to all other modules in an application program and cannot be isolated

via namespaces. Only those variable identifiers starting with

letters or an underscore are kept in a module's symbol table.

All other symbols, such as the names <TT><FONT FACE="Courier">STDIN</FONT></TT>,

<TT><FONT FACE="Courier">STDOUT</FONT></TT>, <TT><FONT FACE="Courier">STDERR</FONT></TT>,

<TT><FONT FACE="Courier">ARGV</FONT></TT>, <TT><FONT FACE="Courier">ARGVOUT</FONT></TT>,

<TT><FONT FACE="Courier">ENV</FONT></TT>, <TT><FONT FACE="Courier">Inc</FONT></TT>,

and <TT><FONT FACE="Courier">SIG</FONT></TT> are forced to be

in package <TT><FONT FACE="Courier">_main.</FONT></TT>

<P>

Switching between packages affects only namespaces. All you are

doing when you use one package or another is declaring which symbol

table to use as the default symbol table for lookup of variable

names. Only dynamic variables are affected by the use of symbol

tables. Variables declared by the use of the <TT><FONT FACE="Courier">my</FONT></TT>

keyword are still resolved with the code block they happen to

reside in and are not referenced through symbol tables. In fact,

the scope of a package declaration remains active only within

the code block it is declared in. Therefore, if you switch symbol

tables by using a package within a subroutine, the original symbol

table in effect when the call was made will be restored when the

subroutine returns. 

<P>

Switching symbol tables affects only the default lookup of dynamic

variable names. You can still explicitly refer to variables, file

handles, and so on in a specific package by prepending a <TT><I><FONT FACE="Courier">packageName</FONT></I><FONT FACE="Courier">::</FONT></TT>

to the variable name. You saw what a <I>package context</I> was

when using references in <A HREF="ch3.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch3.htm" >Chapter 3</A>. A package

context simply implies the use of the symbol table by the Perl

interpreter for resolving variable names in a program. By switching

symbol tables, you are switching the package context.

<P>

Modules can be nested within other modules. The nested module

can use the variables and functions of the module it is nested

within. For nested modules, you would have to use <TT><I><FONT FACE="Courier">moduleName</FONT></I><FONT FACE="Courier">::<I>nestedModuleName</I></FONT></TT>

and so on. Using the double colon (<TT><FONT FACE="Courier">::</FONT></TT>)

is synonymous with using a back quote (<TT><FONT FACE="Courier">`</FONT></TT>).

However, the double colon is the preferred, future way of addressing

variables within modules. 

<P>

Explicit addressing of module variables is always done with a

complete reference. For example, suppose you have a module, <TT><FONT FACE="Courier">Investment</FONT></TT>,

which is the default package in use, and you want to address another

module, <TT><FONT FACE="Courier">Bonds</FONT></TT>, which is nested

within the <TT><FONT FACE="Courier">Investment</FONT></TT> module.

In this case, you cannot use <TT><FONT FACE="Courier">Bond::</FONT></TT>.

Instead, you would have to use <TT><FONT FACE="Courier">Investment::Bond::</FONT></TT>

to address variables and functions within the <TT><FONT FACE="Courier">Bond</FONT></TT>

module. Using <TT><FONT FACE="Courier">Bond::</FONT></TT> would

imply the use of a package <TT><FONT FACE="Courier">Bond</FONT></TT>

that is nested within the <TT><FONT FACE="Courier">main</FONT></TT>

module and not within the <TT><FONT FACE="Courier">Investment</FONT></TT>

module. 

<P>

The symbol table for a module is actually stored in an associative

array of the module's names appended with two colons. The symbol

table for a module called <TT><FONT FACE="Courier">Bond</FONT></TT>

will be referred to as the associative array <TT><FONT FACE="Courier">%Bond::</FONT></TT>.

The name for the symbol table for the <TT><FONT FACE="Courier">main</FONT></TT>

module is <TT><FONT FACE="Courier">%main::</FONT></TT>, and can

even be shortened to <TT><FONT FACE="Courier">%::</FONT></TT>.

Similarly, all nested packages have their symbols stored in associative

arrays with double colons separating each nesting level. For example,

in the <TT><FONT FACE="Courier">Bond</FONT></TT> module that is

nested within the <TT><FONT FACE="Courier">Investment</FONT></TT>

module, the associative array for the symbols in the <TT><FONT FACE="Courier">Bond</FONT></TT>

module will be named <TT><FONT FACE="Courier">%Investment::Bond::</FONT></TT>.

<P>

A <TT><FONT FACE="Courier">typeglob</FONT></TT> is really a global

type for a symbol name. You can perform aliasing operations by

assigning to a <TT><FONT FACE="Courier">typeglob</FONT></TT>.

One or more entries in an associative array for symbols will be

used when an assignment via a <TT><FONT FACE="Courier">typeglob</FONT></TT>

is used. The actual value in each entry of the associative array

is what you are referring to when you use the <TT><FONT FACE="Courier">*<I>variableName</I></FONT></TT><I>

</I>notation. Thus, there are two ways of referring to variable

names in a package: 

<BLOCKQUOTE>

<TT><FONT FACE="Courier">*Investment::money = *Investment::bills;

<BR>

<BR>

$Investment::{'money'} = $Investment::{'bills'};</FONT></TT>

</BLOCKQUOTE>

<P>

In the first method, you are referring to the variables via a

<TT><FONT FACE="Courier">typeglob</FONT></TT> reference. The use

of the symbol table, <TT><FONT FACE="Courier">%Investment::</FONT></TT>,

is implied here, and Perl will optimize the lookup for symbols

<TT><FONT FACE="Courier">money</FONT></TT> and <TT><FONT FACE="Courier">bills</FONT></TT>.

This is the faster and preferred way of addressing a symbol. The

second method uses a lookup for the value of a variable addressed

by <TT><FONT FACE="Courier">'money'</FONT></TT> and <TT><FONT FACE="Courier">'bills'</FONT></TT>

in the associative array used for symbols, <TT><FONT FACE="Courier">%Investment::</FONT></TT>

explicitly. This lookup would be done dynamically and will not

be optimized by Perl. Therefore, the lookup will be forced to

check the associative array every time the statement is executed.

As a result, the second method is not efficient and should be

used only for demonstration of how the symbol table is implemented

internally.

<P>

Another example in this statement 

<BLOCKQUOTE>

<TT><FONT FACE="Courier">*kamran = *husain;</FONT></TT>

</BLOCKQUOTE>

<P>

causes variables, subroutines, and file handles that are named

via the symbol <TT><FONT FACE="Courier">kamran</FONT></TT> to

also be addressed via the symbol <TT><FONT FACE="Courier">husain</FONT></TT>.

That is, all symbol entries in the current symbol table with the

key <TT><FONT FACE="Courier">kamran</FONT></TT> will now contain

references to those symbols addressed by the key <TT><FONT FACE="Courier">husain</FONT></TT>.

To prevent such a global assignment, you can use explicit references.

For example, the following statement will let you address the

contents of <TT><FONT FACE="Courier">$husain</FONT></TT> via the

variable <TT><FONT FACE="Courier">$kamran</FONT></TT>: 

<BLOCKQUOTE>

<TT><FONT FACE="Courier">*kamran = \$husain;</FONT></TT>

</BLOCKQUOTE>

<P>

However, any arrays such <TT><FONT FACE="Courier">@kamran</FONT></TT>

and <TT><FONT FACE="Courier">@husain</FONT></TT> will not be the

same. Only what the references specified explicitly will be changed.

To summarize, when you assign one <TT><FONT FACE="Courier">typeglob</FONT></TT>

to another, you affect all the entries in a symbol table regardless

of the type of variable being referred to. When you assign a reference

from one variable type to another, you are only affecting one

entry in the symbol table. 

<P>

A Perl module file has the following format:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">package ModuleName;<BR>

...<BR>

 ####&nbsp;&nbsp;<I>Insert module code </I>####<BR>

...<BR>

1;</FONT></TT>

</BLOCKQUOTE>

<P>

The filename has to be called <TT><FONT FACE="Courier">ModuleName.pm</FONT></TT>.

The name of a module must end in the string <TT><FONT FACE="Courier">.pm</FONT></TT>

by convention. The <TT><FONT FACE="Courier">package</FONT></TT>

statement is the first line of the file. The last line of the

file must contain the line with the <TT><FONT FACE="Courier">1;</FONT></TT>

statement. This in effect returns a <TT><FONT FACE="Courier">true</FONT></TT>

value to the application program using the module. Not using the

<TT><FONT FACE="Courier">1;</FONT></TT> statement will not let

the module be loaded correctly.

<P>

The <TT><FONT FACE="Courier">package</FONT></TT> statement tells

the Perl interpreter to start with a new namespace domain. Basically,

all your variables in a Perl script belong to a package called

<TT><FONT FACE="Courier">main</FONT></TT>. Every variable in the

<TT><FONT FACE="Courier">main</FONT></TT> package can be referred

to as <TT><FONT FACE="Courier">$main'variable</FONT></TT>.

<P>

Here's the syntax for such references:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$packageName'variableName</FONT></TT>

</BLOCKQUOTE>

<P>

The single quote (<TT><FONT FACE="Courier">'</FONT></TT>) is synonymous

with the double colon (<TT><FONT FACE="Courier">::</FONT></TT>)

operator. I cover more uses of the <TT><FONT FACE="Courier">::</FONT></TT>

operator in the next chapter. For the time being, you must remember

that the following two statements are equivalent:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$packageName'variableName;<BR>

$packageName::variableName;</FONT></TT>

</BLOCKQUOTE>

<P>

The double-colon syntax is considered standard in the Perl world.

Therefore, to preserve readability, I use the double-colon syntax

in the rest of this book unless it's absolutely necessary to make

exceptions to prove a point.

<P>

⌨️ 快捷键说明

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