?? ch13.htm
字號(hào):
This line of code displays
<BLOCKQUOTE>
<PRE>
No such file or directory at test.pl line 2.
</PRE>
</BLOCKQUOTE>
<P>
This error message is a bit more informative. It's even better
if you append the text , <TT>stopped</TT>
to the error message like this:
<BLOCKQUOTE>
<PRE>
chdir('/user/printer') or die("$!, stopped");
</PRE>
</BLOCKQUOTE>
<P>
which displays
<BLOCKQUOTE>
<PRE>
No such file or directory, stopped at test.pl line 2.
</PRE>
</BLOCKQUOTE>
<P>
Appending the extra string makes the error message look a little
more professional. If you are really looking for informative error
messages, try this:
<BLOCKQUOTE>
<PRE>
$code = "chdir('/user/printer')";
eval($code) or die("PROBLEM WITH LINE: $code\n$! , stopped");
</PRE>
</BLOCKQUOTE>
<P>
which displays the following:
<BLOCKQUOTE>
<PRE>
PROBLEM WITH LINE: chdir('/user/printer')
No such file or directory , stopped at test.pl line 3.
</PRE>
</BLOCKQUOTE>
<P>
The <TT>eval()</TT> fuNCtion is discussed
in the section, "Example: Using the <TT>eval()</TT>
FuNCtion," later in this chapter. Therefore, I won't explain
what this code is doing other than to say that the <TT>eval()</TT>
fuNCtion executes its arguments as semi-isolated Perl code. First,
the Perl code in <TT>$code</TT> is
executed and then, if an error arises, the Perl code in <TT>$code</TT>
is displayed as text by the <TT>die()</TT>
fuNCtion.
<P>
If you don't want <TT>die()</TT> to
add the script name and line number to the error, add a newline
to the end of the error message. For example:
<BLOCKQUOTE>
<PRE>
chdir('/user/printer') or die("$!\n");
</PRE>
</BLOCKQUOTE>
<P>
displays the following
<BLOCKQUOTE>
<PRE>
No such file or directory
</PRE>
</BLOCKQUOTE>
<H3><A NAME="ExampleUsingtheTTFONTSIZEFACECourierwarnFONTTTFONTSIZEFuNCtionFONT">
Example: Using the <TT>warn()</TT>
FuNCtion</FONT></A></H3>
<P>
The <TT>warn()</TT> fuNCtion has the
same fuNCtionality that <TT>die()</TT>
does except the script is not exited. This fuNCtion is better
suited for nonfatal messages like low memory or disk space conditions.
The next example tries to change to the <TT>/text</TT>
directory. If the connect fails, the consequeNCes are not fatal
because the files can still be written to the current directory.
<BLOCKQUOTE>
<PRE>
chdir('/text') or warn("Using current directory instead of /text,
</FONT><FONT SIZE=2 FACE="ZapfDingbats">Â</FONT><FONT SIZE=2 FACE="Courier">warning");
</PRE>
</BLOCKQUOTE>
<P>
This line of code displays
<BLOCKQUOTE>
<PRE>
Using current directory instead of /text, warning at test.pl line 2.
</PRE>
</BLOCKQUOTE>
<P>
if the <TT>/text</TT> directory does
not exist. As with <TT>die()</TT>,
you can eliminate the script name and line number by ending your
error message with a newline. You could also use the <TT>$!</TT>
variable to display the system error message.
<H2><A NAME="TrappingFatalErrors"><FONT SIZE=5 COLOR=#FF0000>
Trapping Fatal Errors</FONT></A></H2>
<P>
There are times when reporting fatal errors and then exiting the
script are not appropriate responses to a problem. For example,
your script might try to use the <TT>alarm()</TT>
fuNCtion, which is not supported in some versions of Perl. Normally,
using an unsupported fuNCtion causes your problem to exit, but
you can use the <TT>eval()</TT> fuNCtion
to trap the error and avoid ending the script.
<P>
The <TT>eval()</TT> fuNCtion accepts
an expression and then executes it. Any errors generated by the
execution will be isolated and not affect the main program. However,
all fuNCtion definitions and variable modifications do affect
the main program.
<H3><A NAME="ExampleUsingtheTTFONTSIZEFACECourierevalFONTTTFONTSIZEFuNCtionFONT">
Example: Using the <TT>eval()</TT>
FuNCtion</FONT></A></H3>
<P>
You can use the <TT>eval()</TT> fuNCtion
to trap a normally fatal error:
<BLOCKQUOTE>
<PRE>
eval { alarm(15) };
warn() if $@;
eval { print("The print fuNCtion worked.\n"); };
warn() if $@;
</PRE>
</BLOCKQUOTE>
<P>
This program displays the following:
<BLOCKQUOTE>
<PRE>
The Unsupported fuNCtion alarm fuNCtion is unimplemented at test.pl line
2.
...caught at test.pl line 3.
The print fuNCtion worked.
</PRE>
</BLOCKQUOTE>
<P>
The <TT>$@</TT> special variable holds
the error message, if any, returned by the execution of the expression
passed to the <TT>eval()</TT> fuNCtion.
If the expression is evaluated correctly, then <TT>$@</TT>
is an empty string. You probably remember that an empty string
is evaluated as false when used as a conditional expression.
<P>
In an earlier section, "Example: Using the <TT>die()</TT>
FuNCtion," you saw the following code snippet being used:
<BLOCKQUOTE>
<PRE>
$code = "chdir('/user/printer')";
eval($code) or die("PROBLEM WITH LINE: $code\n$! , stopped");
</PRE>
</BLOCKQUOTE>
<P>
This program shows that <TT>eval()</TT>
will execute a line of code that is inside a variable. You can
use this capability in many different ways besides simply trapping
fatal errors. The program in Listing 13.2 presents a prompt and
executes Perl code as you type it. Another way of looking at this
program is that it is an interactive Perl interpreter.
<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>Loop until the user enters </I><TT><I>exit</I></TT><I>.
<BR>
Print the prompt.<BR>
Get a line of input from </I><TT><I>STDIN</I></TT><I>
and remove the ending linefeed.<BR>
Execute the line.<BR>
If the executed code set the </I><TT><I>$@</I></TT><I>
error message variable, display the error message as a warning.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 13.2 13LST02.PL-Using Perl Interactively
<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
do {
print("> ");
chop($_ = <>);
eval($_);
warn() if $@;
} while ($_ ne "exit");
</PRE>
</BLOCKQUOTE>
<HR>
<P>
When you run this program, you will see a <TT>></TT>
prompt. At the prompt, you can type in any Perl code. When you
press Enter, the line is executed. You can even define fuNCtions
you can use later in the interactive session. The program can
be stopped by typing <TT>exit</TT>
at the command line.
<P>
If you like powerful command-line environments, you can build
on this small program to create a personalized system. For example,
you might need to perform a backup operation before leaving work.
Instead of creating a batch file (under DOS) or a shell file (under
UNIX), you can add a new command to the Perl interactive program,
as in Listing 13.3.
<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>Loop until the user enters </I><TT><I>exit</I></TT><I>.
<BR>
Print the prompt.<BR>
Get a line of input from </I><TT><I>STDIN</I></TT><I>
and remove the ending linefeed.<BR>
If the inputted line begins with </I><TT><I>do#</I></TT><I>,
then a custom command has been entered.<BR>
Process the </I><TT><I>do#backup</I></TT><I>
custom command.<BR>
See if the user needs help.<BR>
Otherwise, use the </I><TT><I>eval()</I></TT><I>
fuNCtion to execute the inputted line.<BR>
If the executed code set the </I><TT><I>$@</I></TT><I>
error message variable, display the error message as a warning.</I>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 13.3 13LST03.PL-An Interactive Perl Interpreter
that Understands Custom Commands<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
sub backItUp {
'\backup /user/*';
'delete /user/*.bak'
}
sub help {
print("do#backup will perform the nightly backup\n");
print("help will display this message.\n\n");
}
do {
print("> ");
chop($_ = <>);
if (/^do#/) {
backItUp)() if /backup/;
}
elsif (/^\s*help/) {
help();
}
else {
eval($_);
warn() if $@;
}
} while ($_ ne "exit");
</PRE>
</BLOCKQUOTE>
<HR>
<P>
This program invokes the backup program and deletes the backup
files if you enter <TT>do#backup</TT>
at the <TT>></TT> prompt. Of course,
you need to modify this program to perform the customized commands
you'd like to have. This technique also enables you to centralize
your administrative tasks, which will make them easier to document
and maintain.<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Tip</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
If you are running Perl on a DOS or Windows machine, consider replacing your small batch utility programs with one Perl interpreter and some customized commands. This saves on hard disk space if you use a lot of batch files because each file may take up
to 4,096 bytes, regardless of its actual size.</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<H2><A NAME="WhatIsaSignal"><FONT SIZE=5 COLOR=#FF0000>
What Is a Signal?</FONT></A></H2>
<P>
<I>Signals</I> are messages sent by the operating system to the
process running your Perl script. At any time, a signal that must
be answered can be sent to your process. Normally, a default handler
is used to take care of a signal. For example, under Windows 95,
when you press the Ctrl+C key combination, your process is sent
an <TT>INT</TT> or interrupt signal.
The default handler responds by ending the process and displays
the following message:
<BLOCKQUOTE>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -