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

📄 ch4.htm

📁 美国Macmillan出版社编写的Perl教程《Perl CGI Web Pages for WINNT》
💻 HTM
📖 第 1 页 / 共 4 页
字号:
&hey_now($a); # to create Hey, now! Here's Hank!

</PRE>

</BLOCKQUOTE>

<P>

or

<BLOCKQUOTE>

<PRE>

&amp;hey_now(&quot;Artie&quot;)+&amp;hey_now(&quot;Bob&quot;); # to create

# Hey, now! Here's Artie! Hey, now! Here's Bob!

</PRE>

</BLOCKQUOTE>

<P>

If you want to use more than one parameter in the @_ array, then

you might write a script like this:

<BLOCKQUOTE>

<PRE>

sub hey_now {

print &quot;$_[0], $_[1]!\n&quot;;

}

&amp;hey_now(&quot;Hey,&quot;,&quot; now!&quot;); # which would print

# Hey, now!

</PRE>

</BLOCKQUOTE>

<P>

where only those parameters defined in the script are examined.

<P>

Using the @_ variable is different because it is local to the

subroutine, unlike previous cases where other variables were global

to the entire script. A global value can be given to @_, but it

has to be done before the subroutine is invoked, and then restored

after the subroutine is completed. One result of this local variable

feature is that a subroutine can pass arguments to another subroutine

without the hassle of having to restate the value in the first

subroutine. Each subroutine keeps its own @_ variable.

<P>

If we update a previous example, we can add the @_ variable:

<BLOCKQUOTE>

<PRE>

sub two_variables {$_[&Oslash;] + $_[1];

{

print &amp;two_variables(1&Oslash;,1); # which prints 11

$S = two_variables(1,2); # which gives $S the

value of 3

</PRE>

</BLOCKQUOTE>

<P>

You can expand this example to manipulate many values at a time,

like so:

<BLOCKQUOTE>

<PRE>

sub plus {

$add = &Oslash;; # start of the addition

foreach $_ (@_) {

$add += $_; # add each new element

}

$add; # the expression evaluated outside the 

nested argument

}

$P = &amp;plus(1,2,3,4); # gives $P the value of 10

print &amp;plus(6,3,5,2); # prints 16

print &amp;plus(1..4); # prints 1&Oslash;

</PRE>

</BLOCKQUOTE>

<P>

If we were already using a variable named $plus somewhere else

in the script, we might encounter a problem because after this

subroutine the value for $plus is completely changed. You can

avoid accidently &quot;stepping on&quot; variable values by understanding

how local variables work with user functions.

<H3><A NAME="UserFunctionsandLocalVariables">

User Functions and Local Variables</A></H3>

<P>

Just like the special @_ variable discussed with user functions,

those that have the ability to have a value locally (scalars,

arrays, and associative arrays) can work this way, too.

<P>

Perl provides the operator local() to designate, or instantiate,

local versions of the variable in question. Using local() might

look like

<BLOCKQUOTE>

<PRE>

sub plus {

local($add); # makes $add a local variable

$add = &Oslash;; # starts the value

foreach $_ (@_) {

$add += $_; # add each element together

}

$add; # the total

}

</PRE>

</BLOCKQUOTE>

<P>

where at the beginning of the subroutine the current value of

the global variable $add is stored away, and a brand new variable

$add is created. This variable starts out with the value undef.

Once the subroutine finishes, the local variable $add dies, and

the global variable $add is restored, with its global value intact.

<BR>

<P>

<CENTER>

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

<TR VALIGN=TOP><TD WIDTH=576><B>WARNING!</B></TD></TR>

<TR VALIGN=TOP><TD WIDTH=576>

<BLOCKQUOTE>

<I>The local () operator is a full, executable operator, and can wreak havoc on your variable values if not used carefully. Good Perl etiquette suggests that you place all your local() operators at the start of your subroutine definitions. </I>

</BLOCKQUOTE>



</TD></TR>

</TABLE></CENTER>

<P>

<P>

You can also use the local() operator on an assignable array list,

which means you can use it like this:

<BLOCKQUOTE>

<PRE>

local($P, @q) = @_;

</PRE>

</BLOCKQUOTE>

<P>

or as the left side to an array assignment operator. The scalar

$P is added to the array @q and held locally in the default array

@_. This array list only has value locally in a block statement

or subroutine.

<H3><A NAME="MoreControlStructures">

More Control Structures</A></H3>

<P>

There are a few more Perl operators that act as control structures

that you should know about. They work very well with subroutines,

and other self-contained Perl script structures, like loops and

block statements. These operators are last, next, and redo, and

they, like the other operators, work both in and out of subroutines,

modifying the action of the subroutine, or block statement.

<P>

The main difference between a subroutine and a block statement

is that the subroutine, once defined, can be called into action

in a script by simply prefacing the subroutine name with the command

Sub. A block statement, being a self-contained function in a script

(like a while loop or array definition), only performs its action

where it is placed in the script, and must be written out in whole

again, if you want to repeat its action. To avoid unnecessary

scripting, subroutines are very popular in Perl.

<H4>The Last Operator</H4>

<P>

There may be a time when you need to get out of a loop before

it has completed all of its cycles. You can use the last operator

to do this. It will cause the loop to stop, and the first statement

following the loop statement block will stop also. A format for

using the last operator might look like this:

<BLOCKQUOTE>

<PRE>

while (a_condition) {

statement1;

statement2;

statement3;

if (another_condition) {

statement4;

statement5;

statement6;

last;

}

statement7;

statement8;

statement9;

}

# last goes here to break the loop

</PRE>

</BLOCKQUOTE>

<P>

where if a_condition in the loop is true, then statements 1, 2,

and 3 are executed, and then ifanother_condition is true, then

statements 4, 5, and 6 are executed, and then the last operator

breaks into the loop and takes you to the end of the entire loop

statement block.

<P>

The last operator works only on those statement blocks of the

for, foreach, while, and naked kind. Naked blocks are those that

belong to no other script construct.

<P>

To demonstrate a more practical use of the last operator, we can

apply it to searching through an e-mail header. The header might

look like this:

<BLOCKQUOTE>

<PRE>

From: jhagey@sentex.net (Jonathan Hagey)

To: reader@my_server.com 

Date: 12-MAY-96 05:23:14 AM EST -0600

Subject: Good luck!

</PRE>

</BLOCKQUOTE>

<P>

Writing good scripts takes practice, patience, and a good manual!

<P>

If you wanted to have a script scan through the e-mail to check

and see if it went to the right person, and that there were no

spelling mistakes in the recipient's e-mail address, you might

try this:

<BLOCKQUOTE>

<PRE>

while (&lt;STDIN&gt;) {

if (/^To:/) { # check to see if it starts

# with To:

if (/reader/) { # correct name

print &quot;It's going to the right person.\n&quot;;

}

last; # have found To:, so exit

} # end of if To: loop

if (/^$/) { # in case of a blank line

last; # when blank line, stop checking

}

} # end of while loop

</PRE>

</BLOCKQUOTE>

<P>

This loop could be adapted to take a variable that held any recipient's

name, to give the script more flexibility. The variable, possibly

the default $_, would replace the static &quot;reader&quot; in

the regular expression and then this variable would use &lt;STDIN&gt;

to read the person's name from your input.

<H4>The Next Operator</H4>

<P>

This operator is used inside a loop, and when it is used it causes

the execution to jump ahead to the next statement block, without

killing the one it occupies.

<P>

The typical format for the next operator is this:

<BLOCKQUOTE>

<PRE>

while (a_condition) {

start_of_block1;	

block1;

end_of_block2;

if (next_condition) {

start_of_block2;

block2;

end_of_block2;

next; # skips next block

}

start_of_block3;

block3;

end_of_block3;

# this is where next goes to

}

</PRE>

</BLOCKQUOTE>

<P>

You might need this function to avoid running unnecessary checks-

which take up valuable online time-on users who have already established

themselves as members of your site, and don't need page after

page of security scrutiny, or have already defined their tastes

as far as sections of your site go, so they are directly moved

by the script to that location.

<H4>The Redo Operator</H4>

<P>

This operator works like the Next operator, only in reverse. If

you need a loop to go back and run through a portion of script

again, you can use the Redo operator. The format is similar:

<BLOCKQUOTE>

<PRE>

while (a_condition) {

# redo returns here

start_of_block1;

block1;

end_of_block1;

if (next_condition) {

start_of_block2;

block2;

end_of_block2;

redo; # goes back up to the marked block

}

start_of_block3;

block3;

end_of_block3;

}

</PRE>

</BLOCKQUOTE>

<P>

It's as straightforward as that.

<H4>Labeling Blocks</H4>

<P>

When dealing with statement blocks in Perl you can use the last,

next, and redo operators to move around your script with great

flexibility. If you wanted to get out of two nested blocks at

the same time, you can use a label with the block statements.

Labeling is a programming method very similar to subroutines,

because once you define the action of the label, you can apply

it as many times as you need to the actions in your script. Labeling

is not as extensive as a subroutine though, as it is only able

to define a specific function, like a particular loop condition.

<P>

Statement blocks are labeled when you give them a name, following

this&nbsp;format:

<BLOCKQUOTE>

<PRE>

LABELNAME: loop_operator(condition) {

statement1;

     statement2;

if(another_condition) {

block_modifier LABELNAME;

}}

</PRE>

</BLOCKQUOTE>

<P>

where the label's name is always in uppercase letters to prevent

confusing it with scalars, arrays, associative arrays, reserved

words, and user functions.

<P>

A typical use for a labeled block might be similar to the following,

⌨️ 快捷键说明

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