📄 ch4.htm
字号:
where you have a nested loop that needs to be exited once a match
has been found:
<BLOCKQUOTE>
<PRE>
FIRST: for ($n = 1; n$ <= 10; $n++) {
SECOND: for ($x = 1; $x <= 10; $x+) {
if ($n*$x == 48) {
print "$n times $x makes 48!\n";
last FIRST;
}
if ($x >= $n) {
next FIRST; # insures $n is always
# the larger of the two numbers
}
}
}
</PRE>
</BLOCKQUOTE>
<P>
where a search for two integers, producing the value 48, is found
using a nested loop. The labeled block provides the way out of
the loop once the two variables, $n and $x, satisfy the condition.
In the previous example only one answer for the search is produced
before the loop is exited.<BR>
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD WIDTH=576><B>NOTE</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=576>
<BLOCKQUOTE>
<I>Block labeling is only effective to exit a loop. You cannot use block labels with the last, next, and redo operators to enter a statement block. </I>
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
Before moving on, it's worthwhile to note that there is one other
way that Perl allows you to place a condition on a statement block.
You can use expression modifiers to accomplish this in much the
same way that a loop works. In fact, you use the same loop modifiers.
<P>
Using an expression modifier is done by using the following format,
where the if modifer is used:
<BLOCKQUOTE>
<PRE>
an_expression if a_control_expression;
</PRE>
</BLOCKQUOTE>
<P>
a_control_expression is the first expression to be evaluated if
that condition is met, then the expression an_expression is modified.
<P>
Using this method you can greatly reduce your scripting time,
and still retain a great deal of sense, or readibility, in your
Perl script. Now that you have all these functions and control
structures straight, let's move on to text processing itself.
<H2><A NAME="ProcessingText"><FONT SIZE=5 COLOR=#FF0000>
Processing Text</FONT></A></H2>
<P>
Perl is great at processing text, but remember that text is not
limited only to letters, but also includes all the ASCII characters.
In order to process text, you need to have some to work with,
so for this chapter you will use the following, taken from the
<I>Summa Theologia</I> by St. Thomas Aquinas:
<P>
Summa Theologica I-II, 90, 1
<P>
Whether law is something pertaining to reason?
<P>
Objection 1. It would seem that law is not something pertaining
to reason. For the Apostle says (Rm. 7:23): "I see another
law in my members," etc. But nothing pertaining to reason
is in the members; since the reason does not make use of a bodily
organ. Therefore law is not something pertaining to reason.
<P>
Objection 2. Further, in the reason there is nothing else but
power, habit, and act. But law is not the power itself of reason.
In like manner, neither is it a habit of reason: because the habits
of reason are the intellectual virtues of which we have spoken
above (57). Nor again is it an act of reason: because then law
would cease, when the act of reason ceases, for instance, while
we are asleep. Therefore law is nothing pertaining to reason.
<P>
Objection 3. Further, the law moves those who are subject to it
to act aright. But it belongs properly to the will to move to
act, as is evident from what has been said above (9, 1). Therefore
law pertains, not to the reason, but to the will; according to
the words of the Jurist (Lib. i, ff., De Const. Prin. leg. i):
"Whatsoever pleaseth the sovereign, has force of law."
<P>
On the contrary, It belongs to the law to command and to forbid.
But it belongs to reason to command, as stated above (17, 1).
Therefore law is something pertaining to reason. I answer that,
Law is a rule and measure of acts, whereby man is induced to act
or is restrained from acting: for "lex" [law] is derived
from "ligare" [to bind], because it binds one to act.
Now the rule and measure of human acts is the reason, which is
the first principle of human acts, as is evident from what has
been stated above (1, 1, ad 3); since it belongs to the reason
to direct to the end, which is the first principle in all matters
of action, according to the Philosopher (Phys. ii). Now that which
is the principle in any genus, is the rule and measure of that
genus: for instance, unity in the genus of numbers, and the first
movement in the genus of movements. Consequently it follows that
law is something pertaining to reason.<BR>
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD WIDTH=576><B>NOTE</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=576>
<BLOCKQUOTE>
<I>Any of you who find St. Thomas Aquinas interesting can check out this site for more information, and an online version of the entire Summa Theologia: <A
HREF="javascript:if(confirm('http://www.epas.utoronto.ca:8080/~loughlin/index.html. \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.epas.utoronto.ca:8080/%7Eloughlin/index.html.'" tppabs="http://www.epas.utoronto.ca:8080/%7Eloughlin/index.html.">http://www.epas.utoronto.ca:8080/~loughlin/index.html.</A> </I>
</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<P>
Searching for key words in the text is a useful application of
<STDIN>. Since the section deals with Aquinas' views on
law, I might want to know where the word "law" occurs
in the section. To receive a list of these lines I could use a
script like this:
<BLOCKQUOTE>
<PRE>
while (<STDIN>) {
print if /law/;
}
</PRE>
</BLOCKQUOTE>
<P>
where I would receive this output.
<P>
<BLOCKQUOTE>
Whether law is something pertaining to reason? <BR>
Objection 1. It would seem that law is not something<BR>
"I see another law in my members," etc. But nothing
<BR>
law is not something pertaining to reason.<BR>
else but power, habit, and act. But law is not the<BR>
law would cease, when the act of reason ceases, for<BR>
instance, while we are asleep. Therefore law is nothing<BR>
Objection 3. Further, the law moves those who are<BR>
been said above (9, 1). Therefore law pertains, not to<BR>
"Whatsoever pleaseth the sovereign, has force of law."
<BR>
On the contrary, It belongs to the law to command and<BR>
stated above (17, 1). Therefore law is something<BR>
restrained from acting: for "lex" [law] is derived from
<BR>
Consequently it follows that law is something
</BLOCKQUOTE>
<P>
This output can be sent to a file, which can then be stored, or
sent to a satisfy a client's request. You would do this by using
filehandles.
<H4>Filehandles</H4>
<P>
In Perl we have already touched on three filehandles in our script
examples from previous chapters: <STDIN>, <STDOUT>,
and <STDERR>, and we didn't even realize we were doing so.
This is because these filehandles are special in Perl, being the
default files Perl moves data in and out of. A filehandle is
a name given to the I/O connection between Perl and whatever it
is dealing with. Other filehandles are defined in each script.
Like labeled blocks, filehandles are written to code using all
uppercase letters. Filehandles are opened with the open() operator
in this format:
<BLOCKQUOTE>
<PRE>
open (FILEHANDLE, "outside_file_name");
</PRE>
</BLOCKQUOTE>
<P>
where FILEHANDLE is the name of the filehandle you've created
and outside_file_name is the name of the file or device (since
you could send something to a printer) that you are sending data
to or receiving data from FILEHANDLE. This particular statement
opens FILEHANDLE for takingdata, or reading, from it.
<P>
If you want to put data into, or write, to FILEHANDLE, then you
would use this format:
<BLOCKQUOTE>
<PRE>
open (FILEHANDLE, ">outside_file_name");
</PRE>
</BLOCKQUOTE>
<P>
or you can append the file by adding another ">"
symbol, like so:
<BLOCKQUOTE>
<PRE>
open (FILEHANDLE, ">>outside_file_name");
</PRE>
</BLOCKQUOTE>
<P>
If the file you are trying to open is busy, not there, or otherwise
inaccessible to your Perl script, you will get the false value
undef returned instead of the file contents. You can have the
script notify you that this has happened by using the die operator,
explained shortly.
<P>
When your script is done with a filehandle, you use the operator
close() to close it, like this:
<BLOCKQUOTE>
<PRE>
close (FILEHANDLE);
</PRE>
</BLOCKQUOTE>
<P>
If you need to reopen the filehandle later, you need not insert
a close argument until the end, because Perl will close the last
incantation of the file in question automatically and re-open
it with the new open operator.
<P>
When a filehandle is opened, but the attempt fails, that filehandle
can still appear later in your script and cause problems. Perl
provides the die() operator to deal with this problem.
<BLOCKQUOTE>
<PRE>
To use the die operator to report a failure in opening a filehandle you can use this format:<B>
</B>open (FILEHANDLE,">/dir/path/name") ||
die "The script has failed.";
</PRE>
</BLOCKQUOTE>
<P>
where the die operator will write the data of the failed filehandle
into <STDERR>. When the die operator is implemented by Perl,
you will receive the program name and line number of the failed
code in the message alerting you that your script has died. You
can customize each returned "die" statement by including
the filehandle name, or other signifier, so you will know which
filehandle has failed. If you don't want that information returned
with the alert message, add a \n to the die argument, like this:
<BLOCKQUOTE>
<PRE>
open (FILEHANDLE,">/dir/path/name") ||
die "The script has failed.\n";
</PRE>
</BLOCKQUOTE>
<P>
and that information will be erased.
<P>
You can use filehandles in text searches for all kinds of problems,
such as the administration duty of finding passwords in an unencrypted
password file, by doing this:
<BLOCKQUOTE>
<PRE>
open(PW,"/user/passwd");
while (<PW>) {
chop:
print "This password is already taken.\n";
</PRE>
</BLOCKQUOTE>
<P>
where the filehandle name PW is used just like <STDIN> and
the other reserved filehandles.
<P>
To write to a file using filehandles, follow this format:
<BLOCKQUOTE>
<PRE>
print FILEHANDLE "Text to be written\n";
</PRE>
</BLOCKQUOTE>
<P>
where the data in the quotes is put into the file associated with
FILEHANDLE.
<P>
Using all this you can create a script that takes data from one
file and places it into another:
<BLOCKQUOTE>
<PRE>
open(FIRST,$f) || die "$f will not open.";
open(SECOND,$s) || die "$s is not found.";
while (<FIRST>) { # takes data from $f
print SECOND $_; # write line to $s
}
close(FIRST);
close(SECOND);
</PRE>
</BLOCKQUOTE>
<P>
where you have included the fail safe die operator as well.
<P>
There is a problem when we use filehandles. If we don't check
whether there is already an existing file of the same name before
we write something to, or create a new file using filehandles,
then we will completely overwrite it, and lose its data. This
is something that people in the UNIX world understand well, but
those of us using Windows are used to being prompted before doing
such a thing. To prevent this from happening, Perl has file tests.
<H3><A NAME="FileTests">
File Tests</A></H3>
<P>
To prevent your script from overwriting an existing file, you
can use the file test -e before the filehandle to test if it exists,
like so:
<BLOCKQUOTE>
<PRE>
-e FILEHANDLE
</PRE>
</BLOCKQUOTE>
<P>
or before the scalar associated with a filehandle, like this:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -