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

📄 ch8.htm

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

<P>

There is one more twist that I would like to show you using this

data structure. Let's see how to dynamically add information.

First, we'll look at adding an entire data record, and then we'll

look at adding new members to an existing data record. Listing

8.7 shows you can use a standard hash assignment to dynamically

create a data record.

<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>Assign a refereNCe to a hash to the &quot;MRD-300&quot; key

in the </I><TT><I>%database </I></TT><I>associative

array.<BR>

Assign the refereNCe to the hash associated with the key &quot;MRD-300&quot;

to the </I><TT><I>$refCustomer</I></TT><I>

variable.<BR>

Print the value associated with the key &quot;Name&quot; inside

hash refereNCed by </I><TT><I>$refCustomer</I></TT><I>.

<BR>

Print the value associated with the key &quot;Address&quot; inside

hash refereNCed by </I><TT><I>$refCustomer</I></TT><I>.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 8.7&nbsp;&nbsp;08LST07.PL-Creating a Record Using Hash

Assignment<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

$database{&quot;MRD-300&quot;} = {

    &quot;Name&quot;    =&gt; &quot;Nathan Hale&quot;,

    &quot;Address&quot; =&gt; &quot;999 Centennial Ave.&quot;,

    &quot;Town&quot;    =&gt; &quot;AnyTown&quot;,

    &quot;State&quot;   =&gt; &quot;AnyState&quot;,

    &quot;Zip&quot;     =&gt; &quot;12345-1234&quot;

};



$refCustomer = $database{&quot;MRD-300&quot;};

print(%{$refCustomer}-&gt;{&quot;Name&quot;} . &quot;\n&quot;);

print(%{$refCustomer}-&gt;{&quot;Address&quot;} . &quot;\n&quot;);

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

Nathan Hale

999 Centennial Ave.

</PRE>

</BLOCKQUOTE>

<P>

Notice that by using a temporary variable (<TT>$refCustomer</TT>),

the program code is more readable. The alternative would be this:

<BLOCKQUOTE>

<PRE>

print(%{$database{&quot;MRD-300&quot;}}-&gt;{&quot;Name&quot;} . &quot;\n&quot;);

</PRE>

</BLOCKQUOTE>

<P>

Most programmers would agree that using the temporary variable

aids in the understanding of the program.

<P>

Our last data structure example will show how to add members to

an existing customer record. Listing 8.8 shows how to add two

phone number members to customer record MRD-300.

<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>Assign a refereNCe to an anonymous fuNCtion to </I><TT><I>$codeRef</I></TT><I>.

This fuNCtion will print the elements of the </I><TT><I>%database</I></TT><I>

hash. Because each value in the </I><TT><I>%database</I></TT><I>

hash is a refereNCe to another hash, the fuNCtion has an inner

loop to derefereNCe the sub-hash.<BR>

Assign a refereNCe to a hash to the &quot;MRD-300&quot; key in

the </I><TT><I>%database </I></TT><I>associative

array.<BR>

Call the anonymous routine by derefereNCing </I><TT><I>$codeRef

to print the contents of %database</I></TT><I>. This is

done by surrounding the code refereNCe variable with curly braces

and prefixing it with a </I><TT><I>&amp;</I></TT><I>

to indicate that it should be derefereNCed as a fuNCtion.<BR>

Assign the refereNCe to the hash associated with the key &quot;MRD-300&quot;

to the </I><TT><I>$refCustomer</I></TT><I>

variable.<BR>

Add &quot;Home Phone&quot; as a key to the hash associated with

the &quot;MRD-300&quot; key.<BR>

Add &quot;Business Phone&quot; as a key to the hash associated

with the &quot;MRD-300&quot; key.<BR>

Call the anonymous routine by derefereNCing </I><TT><I>$codeRef

to print the contents of %database</I></TT><I>.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 8.8&nbsp;&nbsp;08LST08.PL-How to Dynamically Add Members

to a Data Structure<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

$codeRef = sub {

    while (($key, $value) = each(%database)) {

        print(&quot;$key = {\n&quot;);

        while (($innerKey, $innerValue) = each(%{$value})) {

            print(&quot;\t$innerKey =&gt; $innerValue\n&quot;);

        }

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

    }

};



$database{&quot;MRD-300&quot;} = {

    &quot;Name&quot;    =&gt; &quot;Nathan Hale&quot;,

    &quot;Address&quot; =&gt; &quot;999 Centennial Ave.&quot;,

    &quot;Town&quot;    =&gt; &quot;AnyTown&quot;,

    &quot;State&quot;   =&gt; &quot;AnyState&quot;,

    &quot;Zip&quot;     =&gt; &quot;12345-1234&quot;

};



# print database before dynamic changes.

&amp;{$codeRef};



$refCustomer = $database{&quot;MRD-300&quot;};

%{$refCustomer}-&gt;{&quot;Home Phone&quot;}     = &quot;(111) 511-1322&quot;;

%{$refCustomer}-&gt;{&quot;Business Phone&quot;} = &quot;(111) 513-4556&quot;;



# print database after dynamic changes.

&amp;{$codeRef};

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

MRD-300 = {

        Town =&gt; AnyTown

        State =&gt; AnyState

        Name =&gt; Nathan Hale

        Zip =&gt; 12345-1234

        Address =&gt; 999 Centennial Ave.

};



MRD-300 = {

        Town =&gt; AnyTown

        State =&gt; AnyState

        Name =&gt; Nathan Hale

        Home Phone =&gt; (111) 511-1322

        Zip =&gt; 12345-1234

        Business Phone =&gt; (111) 513-4556

        Address =&gt; 999 Centennial Ave.

};

</PRE>

</BLOCKQUOTE>

<P>

This example does two new things. The first thing is that it uses

an anonymous fuNCtion refereNCed by <TT>$codeRef</TT>.

This is done for illustration purposes. There is no reason to

use an anonymous fuNCtion. There are actually good reasons for

you not to do so in normal programs. I think that anonymous fuNCtions

make programs much harder to understand.<BR>

<p>

<CENTER>

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

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

<TR><TD>

<BLOCKQUOTE>

When helper fuNCtions are small and easily understood, I like to place them at the beginning of code files. This helps me to quickly refresh my memory when coming back to view program code after time spent doing other things.</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<P>

The second thing is that a regular hash assignment statement was

used to add values. You can use any of the array fuNCtions with

these nested data structures.

<H3><A NAME="ExampleInterpolatingFuNCtionsInsideDoubleQuotedStrings">

Example: Interpolating FuNCtions Inside Double-Quoted Strings

</A></H3>

<P>

You can use refereNCes to force Perl to interpolate the return

value of a fuNCtion call inside double-quoted strings. This helps

to reduce the number of temporary variables needed by your program.

<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 the </I><TT><I>makeLine()</I></TT><I>

fuNCtion from inside a double-quoted string.<BR>

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

fuNCtion.<BR>

Return the dash character repeated a specified number of times.

The first element in the parameter array is the number of times

to repeat the dash.</I>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

print(&quot;Here are  5 dashes ${\makeLine(5)}.\n&quot;);

print(&quot;Here are 10 dashes ${\makeLine(10)}.\n&quot;);



sub makeLine {

    return(&quot;-&quot; x $_[0]);

}

</PRE>

</BLOCKQUOTE>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

Here are  5 dashes -----.

Here are 10 dashes ----------.

</PRE>

</BLOCKQUOTE>

<P>

The trick in this example is that the backslash turns the scalar

return value into a refereNCe, and then the dollar sign and curly

braces turn the refereNCe back into a scalar value that the <TT>print()</TT>

fuNCtion can interpret correctly. If the backslash character is

not used to create the refereNCe to the scalar return value, then

the <TT>${}</TT> derefereNCing operation

does not have a refereNCe to derefereNCe, and you will get an

&quot;initialized value&quot; error.

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

Summary</FONT></A></H2>

<P>

In this chapter you learned about refereNCes. RefereNCes are scalar

variables used to hold the memory locations. When refereNCes are

derefereNCed, the actual value is returned. For example, if the

value of the refereNCe is assigned like this: <TT>$refScalar

= \10</TT>, then, derefereNCing <TT>$refScalar</TT>

would be equal to 10 and would look like this <TT>${$refScalar}</TT>.

You always can create a refereNCe to a value or variable by preceding

it with a backslash. DerefereNCing is accomplished by surrounding

the refereNCe variable in curly braces and preceding the left

curly brace with a character denoting what type of refereNCe it

is. For example, use <TT>@</TT> for

arrays and <TT>&amp;</TT> for fuNCtions.

<P>

There are five types of refereNCes that you can use in Perl. You

can have a refereNCe to scalars, arrays, hashes, fuNCtions, and

other refereNCes. If you need to determine what type of refereNCe

is passed to a fuNCtion, use the <TT>ref()</TT>

fuNCtion.

<P>

The <TT>ref()</TT> fuNCtion returns

a string that indicates which type of refereNCe was passed to

it. If the parameter was not a refereNCe, the undefined value

is returned. You discovered that it is always a good idea to check

refereNCe types to prevent errors caused by passing the wrong

type of refereNCe. An example was given that caused an error by

passing a scalar refereNCe when the fuNCtion expected an array

refereNCe.

<P>

A lot of time was spent discussing data records and how to access

information stored in them. You learned how to step through dissecting

a derefereNCing expression, how to dynamically add new data records

to an associative array, and how to add new data members to an

existing record.

<P>

The last thing covered in this chapter was how to interpolate

fuNCtion calls inside double-quoted strings. You'll use this technique-at

times-to avoid using temporary variables when printing or coNCatenating

the output of fuNCtions to other strings.

<P>

<A HREF="ch9.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch9.htm" >Chapter 9</A> &quot;Using Files,&quot; introduces you to opening,

reading, and writing files. You find out how to store the data

records you've constructed in this chapter to a file for long-term

storage.

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

Review Questions</FONT></A></H2>

<P>

Answers to Review Questions are in Appendix A.

<OL>

<LI>What is a refereNCe?

<LI>How many types of refereNCes are there?

<LI>What does the <TT>ref()</TT> fuNCtion

return if passed a non-refereNCe as a parameter?

<LI>What notation is used to derefereNCe a refereNCe value?

<LI>What is an anonymous array?

<LI>What is a nested data structure?

<LI>What will the following line of code display?<BR>

<BR>

<TT>print(&quot;${\ref(\(1..5))}&quot;);</TT>

<LI>Using the <TT>%database</TT> array

in Listing 8.6, what will the following line of code display?

<BR>

<BR>

<TT>print(%{$database{&quot;MRD-100&quot;}}-&gt;{&quot;Zip&quot;}

. &quot;\n&quot;);</TT>

</OL>

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

Review Exercises</FONT></A></H2>

<OL>

<LI>Write a program that will print the derefereNCed value of

<TT>$ref</TT> in the following line

of code:<BR>

<BR>

<TT>$ref = \\\45;</TT>

<LI>Write a fuNCtion that removes the first element from each

array passed to it. The return value of the fuNCtion should be

the number of elements removed from all arrays.

<LI>Add error-checking to the fuNCtion written in Exercise 3 so

the <TT>undef</TT> value is returned

if one of the parameters is not an array.

<LI>Write a program based on Listing 8.7 that adds a data member

indicating which weekdays a salesman may call the customer with

an id of MRD-300. Use the following as an example:<BR>

<BR>

<TT> &quot;Best days to call&quot; =&gt;

[&quot;Monday&quot;, &quot;Thursday&quot; ]</TT>

</OL>

<HR>



<CENTER><P><A HREF="ch7.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch7.htm"><IMG SRC="pc.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>

<A HREF="#CONTENTS"><IMG SRC="cc.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>

<A HREF="index-1.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/index-1.htm"><IMG SRC="hb.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>

<A HREF="ch9.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch9.htm"><IMG SRC="nc.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A>

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

</BODY>

</HTML>

⌨️ 快捷键说明

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