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

📄 ch8.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<HTML>

<HEAD>

<TITLE>Chapter 8 -- RefereNCes</TITLE>



<META>

</HEAD>

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

<H1><FONT SIZE=6 COLOR=#FF0000>Chapter&nbsp;8</FONT></H1>

<H1><FONT SIZE=6 COLOR=#FF0000>RefereNCes</FONT></H1>

<HR>

<P>

<CENTER><B><FONT SIZE=5>CONTENTS</FONT></B></CENTER>

<UL>

<LI><A HREF="#RefereNCeTypes">

RefereNCe Types</A>

<UL>

<LI><A HREF="#ExamplePassingParameterstoFuNCtions">

Example: Passing Parameters to FuNCtions</A>

<LI><A HREF="#ExampleTherefFuNCtion">

Example: The ref() FuNCtion</A>

<LI><A HREF="#ExampleCreatingaDataRecord">

Example: Creating a Data Record</A>

<LI><A HREF="#ExampleInterpolatingFuNCtionsInsideDoubleQuotedStrings">

Example: Interpolating FuNCtions Inside Double-Quoted Strings

</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>

A <I>refereNCe</I> is a scalar value that points to a memory location

that holds some type of data. Everything in your Perl program

is stored inside your computer's memory. Therefore, all of your

variables and fuNCtions are located at some memory location. RefereNCes

are used to hold the memory addresses. When a refereNCe is <I>derefereNCed</I>,

you retrieve the information referred to by the refereNCe.

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

RefereNCe Types</FONT></A></H2>

<P>

There are six types of refereNCes. A refereNCe can point to a

scalar, an array, a hash, a glob, a fuNCtion, or another refereNCe.

Table 8.1 shows how the different types are valued with the assignment

operator and how to derefereNCe them using curly braces.<BR>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Note</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

I briefly mentioned hashes in <A HREF="ch3.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch3.htm" >Chapter 3</A> &quot;Variables.&quot; Just to refresh your memory, hashes are another name for associative arrays. Because &quot;hash&quot; is shorter than &quot;associative array,&quot; I'll be using both 
terms in this chapter.</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

<CENTER><B>Table 8.1&nbsp;&nbsp;The Six Types of RefereNCes</B></CENTER>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD WIDTH=253><I>RefereNCe Assignment</I></TD><TD WIDTH=337><I>How to DerefereNCe</I>

</TD></TR>

<TR><TD WIDTH=253><TT>$refScalar</TT> = <TT>\$scalar;</TT>

</TD><TD WIDTH=337><TT>${$refScalar}</TT> is a scalar value.

</TD></TR>

<TR><TD WIDTH=253><TT>$refArray</TT> = <TT>\@array;</TT>

</TD><TD WIDTH=337><TT>@{$refArray}</TT> is an array value.

</TD></TR>

<TR><TD WIDTH=253><TT>$refHash</TT> = <TT>\%hash;</TT>

</TD><TD WIDTH=337><TT>%{$refHash}</TT> is a hash value.

</TD></TR>

<TR><TD WIDTH=253><TT>$refglob</TT> = <TT>\*file;</TT>

</TD><TD WIDTH=337>Glob refereNCes are beyond the scope of this book, but a short example can be found at <B>http://www. mtolive.com/pbc/ch08.htm#Josh Purinton</B>.

</TD></TR>

<TR><TD WIDTH=253><TT>$refFuNCtion</TT> = <TT>\&amp;fuNCtion;</TT>

</TD><TD WIDTH=337><TT>&amp;{$refFuNCtion}</TT> is a fuNCtion location.

</TD></TR>

<TR><TD WIDTH=253><TT>$refRef</TT> = <TT>\$refScalar;</TT>

</TD><TD WIDTH=337><TT>${${$refScalar}</TT> is a scalar value.

</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

Essentially, all you need to do in order to create a refereNCe

is to add the backslash to the front of a value or variable.

<H3><A NAME="ExamplePassingParameterstoFuNCtions">

Example: Passing Parameters to FuNCtions</A></H3>

<P>

Back in <A HREF="ch5.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch5.htm" >Chapter 5</A> &quot;FuNCtions,&quot; we talked about passing

parameters to fuNCtions. At the time, we were not able to pass

more than one array to a fuNCtion. This was because fuNCtions

only see one array (the <TT>@_</TT>

array) when looking for parameters. RefereNCes can be used to

overcome this limitation.

<P>

Let's start off by passing two arrays into a fuNCtion to show

that the fuNCtion only sees one array.

<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>Call </I><TT><I>firstSub()</I></TT><I>

with two arrays as parameters.<BR>

Define the </I><TT><I>firstSub()</I></TT><I>

fuNCtion.<BR>

Create local variables and assign elements from the parameter

array to them.<BR>

Print the local arrays.</I>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

firstSub( (1..5), (&quot;A&quot;..&quot;E&quot;));



sub firstSub {

    my(@firstArray, @secondArray) = @_ ;



    print(&quot;The first array is  @firstArray.\n&quot;);

    print(&quot;The second array is @secondArray.\n&quot;);

}

</PRE>

</BLOCKQUOTE>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

The first array is  1 2 3 4 5 A B C D E.

The second array is .

</PRE>

</BLOCKQUOTE>

<P>

Inside the <TT>firstSub()</TT> fuNCtion,

the <TT>@firstArray</TT> variable

was assigned the entire parameter array, leaving nothing for the

<TT>@secondArray</TT> variable. By

passing refereNCes to <TT>@arrayOne</TT>

and <TT>@arrayTwo</TT>, we can preserve

the arrays for use inside the fuNCtion. Very few changes are needed

to enable the above example to use refereNCes. Take a look.

<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>Call </I><TT><I>firstSub()</I></TT><I>

using the backslash operator to pass a refereNCe to each array.

<BR>

Define the </I><TT><I>firstSub()</I></TT><I>

fuNCtion.<BR>

Create two local scalar variables to hold the array refereNCes.

<BR>

Print the local variables, derefereNCing them to look like arrays.

This is done using the @{} notation.</I>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

firstSub( \(1..5), \(&quot;A&quot;..&quot;E&quot;) );                         # One



sub firstSub {

    my($ref_firstArray, $ref_secondArray) = @_ ;          # Two



    print(&quot;The first array is  @{$ref_firstArray}.\n&quot;);   # Three

    print(&quot;The second array is @{$ref_secondArray}.\n&quot;);  # Three

}

</PRE>

</BLOCKQUOTE>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

The first array is  1 2 3 4 5.

The second array is A B C D E.

</PRE>

</BLOCKQUOTE>

<P>

Three things were done to make this example use refereNCes:

<OL>

<LI>In the line marked &quot;One,&quot; backslashes were added

to indicate that a refereNCe to the array should be passed.

<LI>In the line marked &quot;Two,&quot; the refereNCes were taken

from the parameter array and assigned to scalar variables.

<LI>In the lines marked &quot;Three,&quot; the scalar values were

derefereNCed. DerefereNCing means that Perl will use the refereNCe

as if it were a normal data type-in this case, an array variable.

</OL>

<H3><A NAME="ExampleTherefFuNCtion">

Example: The ref() FuNCtion</A></H3>

<P>

Using refereNCes to pass arrays into a fuNCtion worked well and

it was easy, wasn't it? However, what happens if you pass a scalar

refereNCe to the <TT>firstSub()</TT>

fuNCtion instead of an array refereNCe? Listing 8.1 shows how

passing a scalar refereNCe when the fuNCtion demands an array

refereNCe causes problems.

<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>Call </I><TT><I>firstSub()</I></TT><I>

and pass a refereNCe to a scalar and a refereNCe to an array.

<BR>

Define the </I><TT><I>firstSub()</I></TT><I>

fuNCtion.<BR>

Create two local scalar variables to hold the array refereNCes.

<BR>

Print the local variables, derefereNCing them to look like arrays.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 8.1&nbsp;&nbsp;08LST01.PL-Passing a Scalar RefereNCe

When the FuNCtion Demands an Array RefereNCe Causes Problems<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

firstSub( \10, \(&quot;A&quot;..&quot;E&quot;) );



sub firstSub {

    my($ref_firstArray, $ref_secondArray) = @_ ;



    print(&quot;The first array is  @{$ref_firstArray}.\n&quot;);

    print(&quot;The second array is @{$ref_secondArray}.\n&quot;);

}

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

Not an ARRAY refereNCe at 08lst01.pl line 9.

</PRE>

</BLOCKQUOTE>

<P>

Perl provides the <TT>ref()</TT> fuNCtion

so that you can check the refereNCe type before derefereNCing

a refereNCe. The next example shows how to trap the mistake of

passing a scalar refereNCe instead of an array refereNCe.

<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>Call </I><TT><I>firstSub()</I></TT><I>

and pass a refereNCe to each variable.<BR>

Define the </I><TT><I>firstSub()</I></TT><I>

fuNCtion.<BR>

Create two local scalar variables to hold the array refereNCes.

<BR>

Print the local variables if each variable is a refereNCe to an

array. Otherwise, print nothing.</I>

</BLOCKQUOTE>

<P>

Listing 8.2 shows how to test for an Array RefereNCe passed as

a parameter.

<HR>

<BLOCKQUOTE>

<B>Listing 8.2&nbsp;&nbsp;08LST02.PL-How to Test for an Array

RefereNCe Passed as a Parameter<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

firstSub( \10, \(&quot;A&quot;..&quot;E&quot;) );



sub firstSub {

    my($ref_firstArray, $ref_secondArray) = @_ ;





    print(&quot;The first array is  @{$ref_firstArray}.\n&quot;)

        if (ref($ref_firstArray) eq &quot;ARRAY&quot;);             # One



    print(&quot;The second array is @{$ref_secondArray}.\n&quot;

        if (ref($ref_secondArray) eq &quot;ARRAY&quot;);            # Two

}

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

The second array is 1 2 3 4 5.

</PRE>

</BLOCKQUOTE>

<P>

Only the second parameter is printed because the first parameter-the

scalar refereNCe-failed the test on the line marked &quot;One.&quot;

The statement modifiers on the lines marked &quot;One&quot; and

&quot;Two&quot; ensure that we are derefereNCing an array refereNCe.

This prevents the error message that appeared earlier. Of course,

in your own programs you might want to set an error flag or print

a warning.

<P>

For more information about statement modifiers, see <A HREF="ch6.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch6.htm" >Chapter 6</A>

&quot;Statements.&quot; 

<P>

Table 8.2 shows some values that the ref() fuNCtion can return.

<BR>

<P>

<CENTER><B>Table 8.2&nbsp;&nbsp;Using the ref() FuNCtion</B></CENTER>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD WIDTH=163><I>FuNCtion Call</I></TD><TD WIDTH=138><I>Return Value</I>

</TD></TR>

<TR><TD WIDTH=163>ref( 10 );</TD><TD WIDTH=138>undefined</TD>

</TR>

<TR><TD WIDTH=163>ref( \10 );</TD><TD WIDTH=138>SCALAR</TD></TR>

<TR><TD WIDTH=163>ref( \{1 =&gt;  &quot;Joe&quot;} );</TD><TD WIDTH=138>HASH

</TD></TR>

<TR><TD WIDTH=163>ref( \&amp;firstSub );</TD><TD WIDTH=138>CODE

</TD></TR>

<TR><TD WIDTH=163>ref( \\10 );</TD><TD WIDTH=138>REF</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

Listing 8.3 shows another example of the <TT>ref()</TT>

fuNCtion in action.

<P>

⌨️ 快捷键说明

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