📄 ch16.htm
字号:
<P>As you can see, the debugger has quite a few commands to choosefrom, and it is very powerful. Most programmers will not needall of the fuNCtionality that the debugger has. If you learn todisplay script lines, to use breakpoints, and to display variables,you'll be well on your way to solving any logic problem that mayarise.<H3><A NAME="ExamplesDisplayingInformation">Examples: Displaying Information</A></H3><P>The debugger uses the coNCept of a current display line. The <I>currentdisplay line</I> is simply the last line that has been displayedby the <TT>l</TT> command. When thedebugger first starts, the current display line is the first executableline. See Listing 16.1 for some examples.<HR><BLOCKQUOTE><B>Listing 16.1 16LST01.PL-Using the Debugger ListCommands<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>01: package Inventory_item;02: sub new {03: }04:05: package Pen;06: @ISA = (Inventory_item);07:08: sub new {09: }10:11: package Color;12: print("Executing Color statements\n");13: $colors{"blue"} = "Die Lot 13";14: $colors{"red"} = "Die Lot 5";15:16: sub new {17: }18:19: package main;20: print("Executing main statements\n");</PRE></BLOCKQUOTE><HR><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Note</B></TD></TR><TR><TD><BLOCKQUOTE>This listing is identical to Listing 14.5 except that the guts of the fuNCtions have been removed. This was done simply to shorten the listing.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>If you load this script into the debugger (<TT>perl-d 16lst01.pl</TT>), you will see that the first displayedline is line 6. The lines before line 6 are <TT>package</TT>and <TT>fuNCtion</TT> statements.Line 6 will also be the current execution line.<P>If you issue the <TT>l</TT> debuggercommand, lines 6 to 15 are displayed:<BLOCKQUOTE><PRE>6: @ISA = (Inventory_item);7:8: sub new {9: }10:11: package Color;12: print("Executing Color statements\n");13: $colors{"blue"} = "Die Lot 13";14: $colors{"red"} = "Die Lot 5";15:</PRE></BLOCKQUOTE><P>After this display, the current display line is changed to 15,but the current execution line is still line 6. If you issue the<TT>l</TT> debugger command again,lines 16 to 20 are displayed.<P>You can display the first line of your script by using the <TT>l1</TT> debugger command. This command displays the firstline of the script and changes the current display line:<BLOCKQUOTE><PRE>1: package Inventory_item;</PRE></BLOCKQUOTE><P>Because this script uses package names to change the namespacein which the fuNCtions are defined, simply issuing <TT>lnew</TT> does not display a <TT>new()</TT>fuNCtion. Instead, you need to use the double-colon (<TT>::</TT>)notation to specify which namespace to use. For example, <TT>lColor::new</TT> displays<BLOCKQUOTE><PRE>16: sub new {17: }</PRE></BLOCKQUOTE><P>While inside the debugger, you can use the <TT>X</TT>and <TT>V</TT> commands to view variables.These commands are very good for simple variables, but I havenot found them to be useful for complex data structures. For example,Listing 16.2 shows a small program that creates an array withinan array data structure.<HR><BLOCKQUOTE><B>Listing 16.2 16LST02.PL-Using the </B><TT><B><FONT FACE="Courier">X</FONT></B></TT><B>Command to View Arrays<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>sub prtArray { my(@array) = @_; my($index) = 0; foreach (@array) { if (ref($_) eq 'ARRAY') { my($innerIndex) = 0; foreach (@{$array[3]}) { print("\t$innerIndex\t'$_'\n"); $innerIndex++; } } else { print("$index\t'$array[$index]'\n"); } $index++; }}@array = (1, 2, 3, [1, 2, 3], 4); # an array inside an array.1;</PRE></BLOCKQUOTE><HR><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Note</B></TD></TR><TR><TD><BLOCKQUOTE>This listing is for illustrative purposes only. The crude method used to print the data structure is not recommended for practical use. I suggest that you invest time creating a general-use routine that can print more than one type of complex structure. You might also look at the dumpvars module that comes with most, if not all, Perl distributions.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>Load this script into the debugger (<TT>perl-d 16lst01.pl</TT>), use the <TT>s</TT>command to execute the array assignment, and then display <TT>@array</TT>with the <TT>X array</TT> command.Your display should look like this:<BLOCKQUOTE><PRE>@array = ( 0 '1' 1 '2' 2 '3' 3 'ARRAY(0x7c693c)' 4 '4')</PRE></BLOCKQUOTE><P>You can see that the displayed values are not as informative asyou might hope for because of the array refereNCe in element 3.However, because the <TT>prtArray()</TT>fuNCtion is designed to print this type of data structure, callit from the debugger using the <TT>prtArray(@array);</TT>command. This should result in a display like this:<BLOCKQUOTE><PRE>0 '1'1 '2'2 '3' 0 '1' 1 '2' 2 '3'4 '4'</PRE></BLOCKQUOTE><P>The <TT>1;</TT> line of code is usedto let you execute the array assignment without the debugger ending.Just ignore it.<H3><A NAME="ExamplesUsingtheFONTSIZEFACELBIHelveticaBlackObliquenFONTFONTSIZECommandFONT">Examples: Using the <FONT SIZE=4 FACE="LBI Helvetica Black Oblique">n</FONT><FONT SIZE=4>Command</FONT></A></H3><P>The <TT>n</TT> command lets you stepover fuNCtion calls in your scripts. This command saves you timebecause you won't need to single-step through every line of everyfuNCtion. The program in Listing 16.3 has three fuNCtions definedand three fuNCtion calls and is used to demonstrate the <TT>n</TT>command.<HR><BLOCKQUOTE><B>Listing 16.3 16LST03.PL-Using the </B><TT><B><FONT FACE="Courier">n</FONT></B></TT><B>Command to Step Over FuNCtion Calls<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>1: sub a {2: print("This is fuNCtion a\n");3: }4:5: sub b {6: print("This is fuNCtion b\n");7: }8:9: sub c {10: print("This is fuNCtion c\n");11: }12:13: a();14: b();15: c();</PRE></BLOCKQUOTE><HR><P>First, let's see the regular path of execution that takes placeusing the <TT>s</TT> command:<BLOCKQUOTE><PRE>13: a();2: print("This is fuNCtion a\n");This is fuNCtion a14: b();6: print("This is fuNCtion b\n");This is fuNCtion b15: c();10: print("This is fuNCtion c\n");This is fuNCtion c</PRE></BLOCKQUOTE><P>If the <TT>n</TT> command is usedinstead of the <TT>s</TT> command,the path of execution stays the same. However, you are promptedafter each fuNCtion call. The lines inside the fuNCtion are stillexecuted, however.<BLOCKQUOTE><PRE>13: a();This is fuNCtion a14: b();This is fuNCtion b15: c();This is fuNCtion c</PRE></BLOCKQUOTE><P>By switching between the <TT>s</TT>and <TT>n</TT> commands, you can decidewhich fuNCtions to step into and which to step over.<H3><A NAME="ExamplesUsingBreakpoints">Examples: Using Breakpoints</A></H3><P>Breakpoints are used to tell the debugger where to stop executionof your script. After the execution is stopped, the debugger promptsyou to enter a debugger command. For example, you might want toset a breakpoint on a line that assigns a complicated expressionto a variable. This allows you to check any variables used inthe expression before it is executed.<P>Listing 16.4 demonstrates the different breakpoint commands youcan use.<HR><BLOCKQUOTE><B>Listing 16.4 16LST05.PL-Sample Program to Test Breakpoints<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>1: sub a {2: my($foo) = @_;3:4: print("This is fuNCtion a. Foo is $foo.\n");5: }6:7: a(10);8: a(5);</PRE></BLOCKQUOTE><HR><P>When the script is first loaded into the debugger, the currentexecution line is 7. Using the <TT>c</TT>command causes the entire program to be executed. A transcript
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -