📄 ch16.htm
字号:
<PRE>
$foo = { };
$bar = 5;
$^W = 0;
print("$foa\n");
print("$bar\n");
$^W = 1;
</PRE>
</BLOCKQUOTE>
<P>
eliminates the display of the <TT>Use of
uninitialized value at test.pl line 4.</TT> error message.
Unfortunately, this technique will not stop all messages, and
the placement of the <TT>$^W</TT>
<TT>=</TT> <TT>0;</TT>
statement seems to affect whether the message will be suppressed.
<BR>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Caution</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
This feature did not seem to be too stable in my version of Perl. If you can't get it to work in your version, don't spend too much time trying to find the problem. It simply may not work properly in your version of Perl, either.</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<H3><A NAME="BeingStrictwithYourVariables">
Being Strict with Your Variables</A></H3>
<P>
In the last chapter, "Modules," the use of modules to
implement pragmas was discussed. One very useful pragma to aid
in debugging is <TT>use strict;</TT>.
This statement does two things:
<UL>
<LI>Forces you to use the <TT>my()</TT>
fuNCtion to declare all variables. When all variables have a local
scope, you avoid problems associated with unintentionally changing
the value of a variable in a fuNCtion.
<LI>Ensures that you can't use accidental symbolic derefereNCing.
This topic was not covered in <A HREF="ch8.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch8.htm" >Chapter 8</A> "RefereNCes,"
because it is relatively advaNCed. If you use the derefereNCing
techniques shown in <A HREF="ch8.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch8.htm" >Chapter 8</A> you won't need to worry about this
requirement.
</UL>
<P>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Tip</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
The strict directory on the CD holds all listings from <A HREF="ch8.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch8.htm" >Chapter 8</A>converted so they work with the <TT>use strict;</TT> pragma: essentially, all the variables needed to be declared local using the <TT>my()</TT> fuNCtion.
</BLOCKQUOTE>
</TD></TR>
</TABLE>
</CENTER>
<P>
<P>
When the <TT>strict</TT> pragma is
used, your script will not compile if the preceding two rules
are violated. For example, if you tried to run the following lines
of code,
<BLOCKQUOTE>
<PRE>
use strict;
$foo = { };
$bar = 5;
print("$foo\n");
print("$bar\n");
</PRE>
</BLOCKQUOTE>
<P>
you would receive these error messages:
<BLOCKQUOTE>
<PRE>
Global symbol "foo" requires explicit package name at test.pl line 3.
Global symbol "bar" requires explicit package name at test.pl line 4.
Global symbol "foo" requires explicit package name at test.pl line 6.
Global symbol "bar" requires explicit package name at test.pl line 7.
Execution of test.pl aborted due to compilation errors.
</PRE>
</BLOCKQUOTE>
<P>
In order to eliminate the messages, you need to declare <TT>$foo</TT>
and <TT>$bar</TT> as local variables,
like this:
<BLOCKQUOTE>
<PRE>
use strict;
my($foo) = { };
my($bar) = 5;
print("$foo\n");
print("$bar\n");
</PRE>
</BLOCKQUOTE>
<P>
I bet you already have guessed that the <TT>my()</TT>
fuNCtion makes the variables local to the <TT>main</TT>
package.
<P>
In the next section, you see how to use the debugger to step through
your programs.
<H3><A NAME="SteppingThroughYourScript">
Stepping Through Your Script</A></H3>
<P>
So far, you've read about how to limit the possibility of errors
appearing in your programs. If, after using the <TT>-w</TT>
and the <TT>strict</TT> pragma, you
still have a problem, it's time to use the <I>debugger</I>.
<P>
What is the debugger? Quite simply, it is an interactive environment
that allows you to execute your script's statements one at a time.
If necessary, you can display the lines of your script, view or
alter variables, and even execute entirely new statements.
<P>
You start the debugger by using the <TT>-d</TT>
command-line option. The following line
<BLOCKQUOTE>
<PRE>
perl -w -d 08lst08.pl
</PRE>
</BLOCKQUOTE>
<P>
starts the debugger and loads the script called <TT>08lst08.pl</TT>.
If you want to invoke the debugger with no script, you need to
perform a small bit of magic, like this
<BLOCKQUOTE>
<PRE>
perl -d -e "1;"
</PRE>
</BLOCKQUOTE>
<P>
to start debugger without any program. I say that this is a bit
of magic because you haven't read about all the different command-line
options available for the Perl interpreter. You see them all in
<A HREF="ch17.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch17.htm" >Chapter 17</A>, "Using the Command-Line Options." The -e
option tells Perl to execute a single Perl statement. In this
case the statement is 1;, which basically means do nothing. It
does, however, stop the interpreter from looking for the name
of a script file on the command line.
<P>
When the debugger starts, your screen will look something like
this:
<BLOCKQUOTE>
<PRE>
Loading DB routines from $RCSfile: perl5db.pl,v $$Revision: 4.1
$$Date: 92/08/07 18:24:07 $
Emacs support available.
Enter h for help.
main::(08lst08.pl:3): my($codeRef);
DB<1>
</PRE>
</BLOCKQUOTE>
<P>
This message tells you that the debugger (<TT>DB</TT>)
routines have been loaded. The <TT>DB<1></TT>
is a prompt that indicates that the debugger is waiting for input.
The line number inside the angle brackets is the current execution
line<I>.</I> The <I>current execution line</I> is that line that
the debugger waits to execute.
<P>
One of the features of the debugger is the capability to insert
breakpoints into your script. A <I>breakpoint</I> is an instruction
that tells the debugger to stop, to display a prompt, and to wait
for input. When the debugger first starts, there are no breakpoints
defined for your program. See the section "Examples: Using
Breakpoints" later in the chapter for more information.
<P>
You can use any of the commands listed in Table 16.11 while using
the debugger. While some of the commands are demonstrated in the
sections that follow the table, you can't hurt anything by experimenting
with any or all of the commands on your own.<BR>
<P>
<CENTER><B>Table 16.1 The Debugger Commands</B></CENTER>
<p>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD WIDTH=133><I>Command</I></TD><TD WIDTH=457><I>Description</I>
</TD></TR>
<TR><TD COLSPAN=2 WIDTH=590><B>Commands That Control Actions</B>
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>a ACTION</TT></CENTER>
</TD><TD WIDTH=457>This command tells the debugger to perform <TT>ACTION</TT> just before the current execution line is executed. Optionally, you can specify a line number. For example, <TT>a 10 print("$numFiles");</TT> executes the
<TT>print</TT> statement before line 10 is executed. If line 10 is inside a loop, the action is performed each time through the loop.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>A</TT></CENTER>
</TD><TD WIDTH=457>Deletes all actions.</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>L</TT></CENTER>
</TD><TD WIDTH=457>Lists all breakpoints and actions.</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>< ACTION</TT></CENTER>
</TD><TD WIDTH=457>Forces the debugger to execute <TT>ACTION</TT> each time the debugger prompt is displayed. This command is great if you need to print the value of certain values each time you are prompted by the debugger.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>> ACTION</TT></CENTER>
</TD><TD WIDTH=457>Forces the debugger to execute <TT>ACTION</TT> after every debugger command you issue.
</TD></TR>
<TR><TD COLSPAN=2 WIDTH=590><B>Commands That Involve Breakpoints</B>
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>b</TT></CENTER>
</TD><TD WIDTH=457>Sets a breakpoint at the current execution line. You can specify a line where the breakpoint should be set. For example, <TT>b 35</TT> sets a breakpoint at line 35. You can also create a conditional breakpoint. For example, <TT>b 35
$numLines == 0</TT> causes the debugger to stop at line 35 only if <TT>$numLines</TT> is equal to zero. Watch conditions can also be attached to fuNCtions; just use the fuNCtion name instead of a line number.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>D</TT></CENTER>
</TD><TD WIDTH=457>Deletes the breakpoint from the current execution line. If you specify a line number, the breakpoint is deleted from that line.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>D</TT></CENTER>
</TD><TD WIDTH=457>Deletes all breakpoints.</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>L</TT></CENTER>
</TD><TD WIDTH=457>Lists all breakpoints and actions.</TD></TR>
<TR><TD COLSPAN=2 WIDTH=590><B>Commands That Display Information</B>
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>l</TT></CENTER>
</TD><TD WIDTH=457>Lets you print out parts of your script. There are several flavors of this command that you can use:
<P>
Using a plain <TT>l</TT> displays about 10 lines of your script.<BR>
Using <TT>l 5+4</TT> displays 4 lines of your script starting with line 5.<BR>
Using <TT>l 4-7</TT> displays lines 4 through 7 of your script.<BR>
Using <TT>l 34</TT> displays line 34 of your script.<BR>
Using <TT>l foo</TT> displays roughly the first 10 lines of the <TT>foo()</TT> fuNCtion.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>L</TT></CENTER>
</TD><TD WIDTH=457>Lists all breakpoints and actions.</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>p EXPR</TT></CENTER>
</TD><TD WIDTH=457>Prints the result of evaluating <TT>EXPR</TT> to the display. It is a shorthand way of saying <TT>print DB::OUT (EXPR)</TT>.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>S</TT></CENTER>
</TD><TD WIDTH=457>Lists all fuNCtion names that are defined. The list will iNClude any fuNCtion defined in modules as well as those in your script.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>T</TT></CENTER>
</TD><TD WIDTH=457>Prints a stack trace. A <I>stack trace</I> displays a list of fuNCtion calls and the line number where the calls were made.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>V</TT></CENTER>
</TD><TD WIDTH=457>Lists all variables that are currently defined from all packages and modules that are loaded. A better form of this command is <TT>V PACKAGE</TT> or <TT>V PACKAGE VARLIST</TT> where <TT>PACKAGE</TT> is the name of a loaded package or
module, and <TT>VARLIST</TT> is a currently defined variable in <TT>PACKAGE</TT>. When specifying variable names, don't use the <TT>$</TT>, <TT>@</TT>, or <TT>%</TT> type specifiers.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>w LINE</TT></CENTER>
</TD><TD WIDTH=457>Displays about 10 lines centered around <TT>LINE</TT>. For example, if you use <TT>w 10</TT>, lines 7 to 16 might display.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>X</TT></CENTER>
</TD><TD WIDTH=457>Lists all variables in the current package. If you have stepped into a fuNCtion that is in package <TT>foo</TT>, the variables in package <TT>foo</TT> are displayed, not those in <TT>main</TT>. You can also specify exactly which
variables to display if needed. When specifying variable names, don't use the <TT>$</TT>, <TT>@</TT>, or <TT>%</TT> type specifiers.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>-</TT></CENTER>
</TD><TD WIDTH=457>Displays about 10 lines of your script that are before the current line. For example, if the current display line is 30, this command might display lines 19 to 29.
</TD></TR>
<TR><TD COLSPAN=2 WIDTH=590><B>Commands That Control Execution</B>
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>s</TT></CENTER>
</TD><TD WIDTH=457>Steps through the lines in your script one at a time. It steps into any user-defined fuNCtion that is called. While single-stepping is slow, you see exactly how your code is being executed.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>N</TT></CENTER>
</TD><TD WIDTH=457>Executes the next statement in your script. Although all fuNCtion calls are executed, it does not follow the execution path inside a fuNCtion. This command enables you to move quicker through the execution of your script than simply
using the <TT>s</TT> command. An example of this is shown in the "Examples: Using the <TT>n</TT> Command" section later in this chapter.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>R</TT></CENTER>
</TD><TD WIDTH=457>Executes the rest of the statements in the current fuNCtion. The debugger pauses for input on the line following the line that made the fuNCtion call.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>C LINE</TT></CENTER>
</TD><TD WIDTH=457>Executes the rest of the statements in your script unless a breakpoint is found before the script ends. You can optionally use this command to create a temporary break by specifying a line number after the <TT>c</TT>. I think of this
command as continue until <TT>LINE</TT>.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>No Command</TT></CENTER>
</TD><TD WIDTH=457>Pressing the Enter key without specifying a command will make the debugger repeat the last <TT>n</TT> or <TT>s</TT> command that was used. This feature makes it a little easier to single-step through your script.
</TD></TR>
<TR><TD COLSPAN=2 WIDTH=590><B>Commands That Work with the Debugger Command History</B>
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>!</TT></CENTER>
</TD><TD WIDTH=457>Re-executes the previous command. You can also specify the number of the previous command to execute. Use the <TT>H</TT> command to get a list of the previous commands. If you specify a negative number, like <TT>! -2</TT>, the debugger
counts backwards from the last executed command.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>H</TT></CENTER>
</TD><TD WIDTH=457>Lists all the debugger commands you have issued. Only commands that cause action are saved in the command history. This means that the <TT>l</TT> and <TT>T</TT> commands are not saved. You can limit the history viewed by specifying a
negative number. For example, <TT>H -5</TT> displays the last five commands you have issued.
</TD></TR>
<TR><TD COLSPAN=2 WIDTH=590><B>Miscellaneous Commands</B></TD>
</TR>
<TR><TD WIDTH=133><CENTER><TT>f FILENAME</TT></CENTER>
</TD><TD WIDTH=457>Causes the debugger to switch to <TT>FILENAME</TT>. The file specified must have already been loaded via the <TT>use</TT> or <TT>require</TT> statements. Please note that some of the documentation that accompanies the Perl interpreter
may indicate that <TT>f</TT> is the <TT>finish</TT> command. It used to be; however, the finish fuNCtionality is now accomplished by the <TT>r</TT> command.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>Q</TT></CENTER>
</TD><TD WIDTH=457>Quits the debugger. You can also use the Ctrl+D key sequeNCe under UNIX and the Ctrl+Z key sequeNCe under DOS and Windows.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>T</TT></CENTER>
</TD><TD WIDTH=457>Toggles trace mode on and off. <I>Trace</I> mode, when on, displays each script line as it is being executed. I don't recommend this option except for very short programs because the lines are displayed so quickly that you won't be able
to read them.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>/pattern/</TT></CENTER>
</TD><TD WIDTH=457>Searches for <TT>pattern</TT> in the currently loaded file. If <TT>pattern</TT> is found, the current display line is changed to the line where <TT>pattern</TT> was found.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>?pattern?</TT></CENTER>
</TD><TD WIDTH=457>Searches backward for <TT>pattern</TT> in the currently loaded file. If <TT>pattern</TT> is found, the current display line is changed to the line where <TT>pattern</TT> was found.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>=</TT></CENTER>
</TD><TD WIDTH=457>Displays any aliases that are currently defined. You can also use it to create aliases. See the section "Examples: Creating Command Aliases" later in this chapter for more information about aliases and the <TT>=</TT> command.
</TD></TR>
<TR><TD WIDTH=133><CENTER><TT>COMMAND</TT></CENTER>
</TD><TD WIDTH=457>Any text that is not recognized as an alias or a debugger command is executed as a Perl statement. See the section "Examples: Using the Debugger as an Interactive Interpreter" later in this chapter for more information about
executing Perl statements inside the debugger.
</TD></TR>
</TABLE>
</CENTER>
<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -