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

📄 ch3.htm

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



<HEAD>

   <TITLE>Chapter 3 -- References</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 3</FONT></H1>

<H1><B><FONT SIZE=5 COLOR=#FF0000>References</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="#IntroductiontoReferences" >Introduction to References</A>

<LI><A HREF="#UsingReferences" >Using References</A>

<LI><A HREF="#TheBackslashOperator" >The Backslash Operator</A>

<LI><A HREF="#ReferencesandArrays" >References and Arrays</A>

<LI><A HREF="#UsingMultidimensionalArrays" >Using Multidimensional Arrays</A>

<LI><A HREF="#ReferencestoSubroutines" >References to Subroutines</A>

<UL>

<LI><A HREF="#UsingSubroutineTemplates" >Using Subroutine Templates</A>

</UL>

<LI><A HREF="#ImplementingStateMachines" >Implementing State Machines</A>

<LI><A HREF="#PassingMoreThanOneArrayintoaSubro" >Passing More Than One Array into a Subroutine</A>

<UL>

<LI><A HREF="#PassbyValueorbyReference" >Pass by Value or by Reference?</A>

</UL>

<LI><A HREF="#ReferencestoFileHandles" >References to File Handles</A>

<UL>

<LI><A HREF="#WhatDoesthevariableOperatorDo" >What Does the <I>*variable</I> Operator Do?</A>

</UL>

<LI><A HREF="#UsingSymbolicReferences" >Using Symbolic References</A>

<UL>

<LI><A HREF="#DeclaringwithCurlyBraces" >Declaring with Curly Braces</A>

<LI><A HREF="#MultidimensionalAssociativeArrays" >Multidimensional Associative Arrays</A>

</UL>

<LI><A HREF="#StrictReferences" >Strict References</A>

<LI><A HREF="#ForMoreInformation" >For More Information</A>

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

</UL>

<HR>

<P>

This chapter describes the use of Perl references and the concept

of pointers. It also shows you how to use references to create

fairly complex data structures and pass pointers, as well as how

to use pointers to subroutines and to pass parameters.

<H2><A NAME="IntroductiontoReferences"><FONT SIZE=5 COLOR=#FF0000>Introduction

to References</FONT></A></H2>

<P>

A <I>reference</I> is simply a pointer to <I>something</I>; it

is very similar to the concept of a <I>pointer</I> in C or PASCAL.

That <I>something</I> could be a Perl variable, array, hash, or

even a subroutine. A reference in your program is simply an address

to a value. How you use the value of that reference is really

up to you as the programmer and what the language lets you get

away with. In Perl, you can use the terms pointer and reference

interchangeably without any loss of meaning.

<P>

There are two types of references in Perl 5 with which you can

work: <I>symbolic </I>and <I>hard</I>.

<P>

A symbolic reference simply contains the name of a variable. Symbolic

references are useful for creating variable names and addressing

them at runtime. Basically, a symbolic reference is like the name

of a file or a soft link on a UNIX system. Hard references are

more like hard links in the file system; that is, a hard link

is merely another path to the same file. In Perl, a hard reference

is another name for a data item.

<P>

Hard references in Perl also keep track of the number of references

to items in an application. When the reference count becomes zero,

Perl automatically frees the item being referenced. If that item

happens to be a Perl object, the object is &quot;destructed,&quot;

that is, freed to the memory pool. Perl is object-oriented in

itself because everything in a Perl application is an object,

including the main package. When the main package terminates,

all other objects within the main object are also terminated.

Packages and modules in Perl further the ease of use of objects

in Perl. Perl modules are covered in <A HREF="ch4.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch4.htm" >Chapter 4</A>,

&quot;Introduction to Perl Modules.&quot;

<P>

When you use a symbolic reference that does not exist, Perl creates

the variable for you and uses it. For variables that already exist,

the value of the variable is substituted instead of the <TT><FONT FACE="Courier">$variable

</FONT></TT>token. This substitution lets you construct variable

names from variable names.

<P>

Consider the following example:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$lang = &quot;java&quot;;<BR>

$java = &quot;coffee&quot;;<BR>

<BR>

print &quot;${lang}\n&quot;;<BR>

print &quot;hot${lang}\n&quot;;<BR>

print &quot;$$lang \n&quot;</FONT></TT>

</BLOCKQUOTE>

<P>

The third <TT><FONT FACE="Courier">print</FONT></TT> line is important.

<TT><FONT FACE="Courier">$$lang</FONT></TT> is first reduced to

<TT><FONT FACE="Courier">$java</FONT></TT>, then the Perl interpreter

will recognize that <TT><FONT FACE="Courier">$java</FONT></TT>

can also be reparsed, and the value of <TT><FONT FACE="Courier">$java</FONT></TT>,

<TT><FONT FACE="Courier">&quot;coffee&quot;</FONT></TT>, is used.

<P>

Symbolic references are created via the <TT><FONT FACE="Courier">${}</FONT></TT>

construct, so <TT><FONT FACE="Courier">${lang}</FONT></TT> translates

to <TT><FONT FACE="Courier">java</FONT></TT>, and <TT><FONT FACE="Courier">hot${java}</FONT></TT>

translates to <TT><FONT FACE="Courier">hotjava</FONT></TT>. If

you want to address a variable name <TT><FONT FACE="Courier">hotjava</FONT></TT>,

you could use the statement: <TT><FONT FACE="Courier">${hot${lang}}</FONT></TT>.

This would be interpreted as, &quot;take the value in <TT><FONT FACE="Courier">$lang</FONT></TT>,

and append it to the word hot. Now take the constructed string

(<TT><FONT FACE="Courier">hotjava</FONT></TT>) and use it as a

name because there is a <TT><FONT FACE="Courier">${}</FONT></TT>

around it.&quot; 

<P>

In other words, the value of the scalar produced by <TT><FONT FACE="Courier">$$lang</FONT></TT>

is taken to be the name of a new variable, and the variable at

<TT><FONT FACE="Courier">$java</FONT></TT> is used. Here's the

output from this example:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">java<BR>

hotjava<BR>

coffee</FONT></TT>

</BLOCKQUOTE>

<P>

Thus, the difference between a hard reference (<TT><FONT FACE="Courier">$lang</FONT></TT>)

and a symbolic reference (<TT><FONT FACE="Courier">$$lang</FONT></TT>)

is how the variable name is derived. In a hard reference, you

are referring to a variable's value directly. With a symbolic

reference, you are using another level of indirection by constructing

or deriving a symbol name from an existing variable.

<P>

References are easy to use in Perl as long as they are used as

scalars. To use hard references as anything but scalars, you have

to explicitly dereference the variable and tell it how to be used.

<H2><A NAME="UsingReferences"><FONT SIZE=5 COLOR=#FF0000>Using

References</FONT></A></H2>

<P>

A <I>scalar value</I> in this chapter refers to a variable, such

as <TT><FONT FACE="Courier">$pointer</FONT></TT>, that contains

one data item. This item is a scalar and any scalar may hold a

hard reference. Arrays and hashes contain scalars; therefore,

they can hold many references. Thus, with judicious use of arrays

and hashes, you can easily build complex data structures of different

combinations of arrays of arrays, arrays of hashes, hashes of

functions, and so on.

<P>

There are several ways to construct references, and you can have

references to just about anything-arrays, scalar variables, subroutines,

file handles, and, yes (to the delight of C programmers), even

to other references.

<P>

To use the value of <TT><FONT FACE="Courier">$pointer</FONT></TT>

as the pointer to an array, you reference the items in the array

as <TT><FONT FACE="Courier">@$pointer</FONT></TT>. The notation

<TT><FONT FACE="Courier">@$pointer</FONT></TT> roughly translates

to &quot;take the value in <TT><FONT FACE="Courier">$pointer</FONT></TT>,

and then use this value as the address to an array.&quot; Similarly,

you use <TT><FONT FACE="Courier">%$pointer</FONT></TT> for hashes.

That is, &quot;take the value of <TT><FONT FACE="Courier">$pointer</FONT></TT>

and interpret is as an address to a hash.&quot; 

<H2><A NAME="TheBackslashOperator"><FONT SIZE=5 COLOR=#FF0000>The

Backslash Operator</FONT></A></H2>

<P>

Using the backslash operator is analogous to using the ampersand

(<TT><FONT FACE="Courier">&amp;</FONT></TT>) operator in C to

pass the address of an operator. This method is usually used to

create a second, new reference to the variable in question. Here's

how to create a reference to a scalar variable:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$variable = 22;<BR>

$pointer = \$variable;<BR>

<BR>

$ice = &quot;jello&quot;<BR>

$iceptr = \$ice;</FONT></TT>

</BLOCKQUOTE>

<P>

Now <TT><FONT FACE="Courier">$pointer</FONT></TT> points to the

location containing the value of <TT><FONT FACE="Courier">$variable</FONT></TT>.

The pointer <TT><FONT FACE="Courier">$iceptr</FONT></TT> points

to <TT><FONT FACE="Courier">jello</FONT></TT>. Even if the original

reference (<TT><FONT FACE="Courier">$variable</FONT></TT>) goes

away, you can still access the value from the <TT><FONT FACE="Courier">$pointer</FONT></TT>

reference. It's a hard reference at work here, so you have to

get rid of both <TT><FONT FACE="Courier">$pointer</FONT></TT>

and <TT><FONT FACE="Courier">$variable</FONT></TT> to free up

the space in which the value of <TT><FONT FACE="Courier">jello</FONT></TT>

is allocated. Similarly, <TT><FONT FACE="Courier">$variable</FONT></TT>

contains the number <TT><FONT FACE="Courier">22</FONT></TT> and

because <TT><FONT FACE="Courier">$pointer</FONT></TT> refers to

<TT><FONT FACE="Courier">$variable</FONT></TT>, dereferencing

the <TT><FONT FACE="Courier">$pointer</FONT></TT> with the statement

<TT><FONT FACE="Courier">$$pointer</FONT></TT> returns a value

of <TT><FONT FACE="Courier">22</FONT></TT>. In a subroutine, both

<TT><FONT FACE="Courier">$variable</FONT></TT> and <TT><FONT FACE="Courier">$pointer</FONT></TT>

have to be declared as &quot;local&quot; or &quot;my&quot; variables.

If they are both not declared as such, at least one of these variables

will persist as a global variable long after the subroutine in

which they are declared returns. As long as either of these variables

exists, the space for storing the numbers will also exist.

<P>

The variable <TT><FONT FACE="Courier">$pointer</FONT></TT> contains

the address of the <TT><FONT FACE="Courier">$variable</FONT></TT>,

not the value itself. To get the value, you have to dereference

<TT><FONT FACE="Courier">$pointer</FONT></TT> with <I>two </I>dollar

signs,<I> </I><TT><FONT FACE="Courier">$$</FONT></TT>. Listing

3.1 illustrates how this works.

<HR>

<BLOCKQUOTE>

<B>Listing 3.1. References to scalars.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">1 #!/usr/bin/perl<BR>

2 <BR>

3 $value = 10;<BR>

4 <BR>

5 $pointer = \$value;<BR>

6 <BR>

7 printf &quot;\n Pointer Address $pointer of&nbsp;&nbsp;$value

\n&quot;;<BR>

8 <BR>

9 printf &quot;\n What Pointer *($pointer) points to $$pointer\n&quot;;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

<TT><FONT FACE="Courier">$value</FONT></TT> in this script is

set to <TT><FONT FACE="Courier">10</FONT></TT>. <TT><FONT FACE="Courier">$pointer</FONT></TT>

is set to point to the address of <TT><FONT FACE="Courier">$value</FONT></TT>.

The two <TT><FONT FACE="Courier">printf</FONT></TT> statements

show how the value of the variable is being referenced. If you

run this script, you'll see something very close to this output:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">Pointer Address SCALAR(0x806c520) of

 10<BR>

<BR>

What Pointer *(SCALAR(0x806c520)) points to 10</FONT></TT>

</BLOCKQUOTE>

<P>

The address shown in the output from your script definitely will

be different from the one shown here. However, you can see that

<TT><FONT FACE="Courier">$pointer</FONT></TT> gave the address,

and <TT><FONT FACE="Courier">$$pointer</FONT></TT> gave the value

of the scalar pointed to by <TT><FONT FACE="Courier">$variable</FONT></TT>.

<P>

The word <TT><FONT FACE="Courier">SCALAR</FONT></TT> followed

by a long hexadecimal number in the address value tells you that

the address points to a scalar variable. The number following

<TT><FONT FACE="Courier">SCALAR</FONT></TT> is the address where

the information of the scalar variable is being kept.

<H2><A NAME="ReferencesandArrays"><FONT SIZE=5 COLOR=#FF0000>References

and Arrays</FONT></A></H2>

<P>

This is perhaps the most important thing you must remember about

Perl: all Perl <TT><FONT FACE="Courier">@ARRAY</FONT></TT>s and

<TT><FONT FACE="Courier">%HASH</FONT></TT>es are always one-dimensional.

As such, the arrays and hashes hold only scalar values and do

not directly contain other arrays or complex data structures.

If it's a member of an array, it's either a data item or a reference

to a data item.

<P>

You can also use the backslash operator on arrays and hashes,

just as you would for scalar variables. For arrays, you use something

like the Perl script in Listing 3.2. 

<HR>

<BLOCKQUOTE>

<B>Listing 3.2. Using array references.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

⌨️ 快捷键说明

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