1*0Sstevel@tonic-gate=head1 NAME 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateperldebtut - Perl debugging tutorial 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gate=head1 DESCRIPTION 6*0Sstevel@tonic-gate 7*0Sstevel@tonic-gateA (very) lightweight introduction in the use of the perl debugger, and a 8*0Sstevel@tonic-gatepointer to existing, deeper sources of information on the subject of debugging 9*0Sstevel@tonic-gateperl programs. 10*0Sstevel@tonic-gate 11*0Sstevel@tonic-gateThere's an extraordinary number of people out there who don't appear to know 12*0Sstevel@tonic-gateanything about using the perl debugger, though they use the language every 13*0Sstevel@tonic-gateday. 14*0Sstevel@tonic-gateThis is for them. 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate=head1 use strict 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gateFirst of all, there's a few things you can do to make your life a lot more 20*0Sstevel@tonic-gatestraightforward when it comes to debugging perl programs, without using the 21*0Sstevel@tonic-gatedebugger at all. To demonstrate, here's a simple script, named "hello", with 22*0Sstevel@tonic-gatea problem: 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate #!/usr/bin/perl 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate $var1 = 'Hello World'; # always wanted to do that :-) 27*0Sstevel@tonic-gate $var2 = "$varl\n"; 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate print $var2; 30*0Sstevel@tonic-gate exit; 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gateWhile this compiles and runs happily, it probably won't do what's expected, 33*0Sstevel@tonic-gatenamely it doesn't print "Hello World\n" at all; It will on the other hand do 34*0Sstevel@tonic-gateexactly what it was told to do, computers being a bit that way inclined. That 35*0Sstevel@tonic-gateis, it will print out a newline character, and you'll get what looks like a 36*0Sstevel@tonic-gateblank line. It looks like there's 2 variables when (because of the typo) 37*0Sstevel@tonic-gatethere's really 3: 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate $var1 = 'Hello World'; 40*0Sstevel@tonic-gate $varl = undef; 41*0Sstevel@tonic-gate $var2 = "\n"; 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gateTo catch this kind of problem, we can force each variable to be declared 44*0Sstevel@tonic-gatebefore use by pulling in the strict module, by putting 'use strict;' after the 45*0Sstevel@tonic-gatefirst line of the script. 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gateNow when you run it, perl complains about the 3 undeclared variables and we 48*0Sstevel@tonic-gateget four error messages because one variable is referenced twice: 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate Global symbol "$var1" requires explicit package name at ./t1 line 4. 51*0Sstevel@tonic-gate Global symbol "$var2" requires explicit package name at ./t1 line 5. 52*0Sstevel@tonic-gate Global symbol "$varl" requires explicit package name at ./t1 line 5. 53*0Sstevel@tonic-gate Global symbol "$var2" requires explicit package name at ./t1 line 7. 54*0Sstevel@tonic-gate Execution of ./hello aborted due to compilation errors. 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gateLuvverly! and to fix this we declare all variables explicitly and now our 57*0Sstevel@tonic-gatescript looks like this: 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #!/usr/bin/perl 60*0Sstevel@tonic-gate use strict; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate my $var1 = 'Hello World'; 63*0Sstevel@tonic-gate my $varl = undef; 64*0Sstevel@tonic-gate my $var2 = "$varl\n"; 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate print $var2; 67*0Sstevel@tonic-gate exit; 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gateWe then do (always a good idea) a syntax check before we try to run it again: 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate > perl -c hello 72*0Sstevel@tonic-gate hello syntax OK 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gateAnd now when we run it, we get "\n" still, but at least we know why. Just 75*0Sstevel@tonic-gategetting this script to compile has exposed the '$varl' (with the letter 'l') 76*0Sstevel@tonic-gatevariable, and simply changing $varl to $var1 solves the problem. 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate=head1 Looking at data and -w and v 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gateOk, but how about when you want to really see your data, what's in that 82*0Sstevel@tonic-gatedynamic variable, just before using it? 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate #!/usr/bin/perl 85*0Sstevel@tonic-gate use strict; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate my $key = 'welcome'; 88*0Sstevel@tonic-gate my %data = ( 89*0Sstevel@tonic-gate 'this' => qw(that), 90*0Sstevel@tonic-gate 'tom' => qw(and jerry), 91*0Sstevel@tonic-gate 'welcome' => q(Hello World), 92*0Sstevel@tonic-gate 'zip' => q(welcome), 93*0Sstevel@tonic-gate ); 94*0Sstevel@tonic-gate my @data = keys %data; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate print "$data{$key}\n"; 97*0Sstevel@tonic-gate exit; 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gateLooks OK, after it's been through the syntax check (perl -c scriptname), we 100*0Sstevel@tonic-gaterun it and all we get is a blank line again! Hmmmm. 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gateOne common debugging approach here, would be to liberally sprinkle a few print 103*0Sstevel@tonic-gatestatements, to add a check just before we print out our data, and another just 104*0Sstevel@tonic-gateafter: 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate print "All OK\n" if grep($key, keys %data); 107*0Sstevel@tonic-gate print "$data{$key}\n"; 108*0Sstevel@tonic-gate print "done: '$data{$key}'\n"; 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gateAnd try again: 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate > perl data 113*0Sstevel@tonic-gate All OK 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate done: '' 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gateAfter much staring at the same piece of code and not seeing the wood for the 118*0Sstevel@tonic-gatetrees for some time, we get a cup of coffee and try another approach. That 119*0Sstevel@tonic-gateis, we bring in the cavalry by giving perl the 'B<-d>' switch on the command 120*0Sstevel@tonic-gateline: 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate > perl -d data 123*0Sstevel@tonic-gate Default die handler restored. 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate Loading DB routines from perl5db.pl version 1.07 126*0Sstevel@tonic-gate Editor support available. 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate Enter h or `h h' for help, or `man perldebug' for more help. 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate main::(./data:4): my $key = 'welcome'; 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gateNow, what we've done here is to launch the built-in perl debugger on our 133*0Sstevel@tonic-gatescript. It's stopped at the first line of executable code and is waiting for 134*0Sstevel@tonic-gateinput. 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gateBefore we go any further, you'll want to know how to quit the debugger: use 137*0Sstevel@tonic-gatejust the letter 'B<q>', not the words 'quit' or 'exit': 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate DB<1> q 140*0Sstevel@tonic-gate > 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gateThat's it, you're back on home turf again. 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate=head1 help 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gateFire the debugger up again on your script and we'll look at the help menu. 148*0Sstevel@tonic-gateThere's a couple of ways of calling help: a simple 'B<h>' will get the summary 149*0Sstevel@tonic-gatehelp list, 'B<|h>' (pipe-h) will pipe the help through your pager (which is 150*0Sstevel@tonic-gate(probably 'more' or 'less'), and finally, 'B<h h>' (h-space-h) will give you 151*0Sstevel@tonic-gatethe entire help screen. Here is the summary page: 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gateDB<1>h 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate List/search source lines: Control script execution: 156*0Sstevel@tonic-gate l [ln|sub] List source code T Stack trace 157*0Sstevel@tonic-gate - or . List previous/current line s [expr] Single step [in expr] 158*0Sstevel@tonic-gate v [line] View around line n [expr] Next, steps over subs 159*0Sstevel@tonic-gate f filename View source in file <CR/Enter> Repeat last n or s 160*0Sstevel@tonic-gate /pattern/ ?patt? Search forw/backw r Return from subroutine 161*0Sstevel@tonic-gate M Show module versions c [ln|sub] Continue until position 162*0Sstevel@tonic-gate Debugger controls: L List break/watch/actions 163*0Sstevel@tonic-gate o [...] Set debugger options t [expr] Toggle trace [trace expr] 164*0Sstevel@tonic-gate <[<]|{[{]|>[>] [cmd] Do pre/post-prompt b [ln|event|sub] [cnd] Set breakpoint 165*0Sstevel@tonic-gate ! [N|pat] Redo a previous command B ln|* Delete a/all breakpoints 166*0Sstevel@tonic-gate H [-num] Display last num commands a [ln] cmd Do cmd before line 167*0Sstevel@tonic-gate = [a val] Define/list an alias A ln|* Delete a/all actions 168*0Sstevel@tonic-gate h [db_cmd] Get help on command w expr Add a watch expression 169*0Sstevel@tonic-gate h h Complete help page W expr|* Delete a/all watch exprs 170*0Sstevel@tonic-gate |[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess 171*0Sstevel@tonic-gate q or ^D Quit R Attempt a restart 172*0Sstevel@tonic-gate Data Examination: expr Execute perl code, also see: s,n,t expr 173*0Sstevel@tonic-gate x|m expr Evals expr in list context, dumps the result or lists methods. 174*0Sstevel@tonic-gate p expr Print expression (uses script's current package). 175*0Sstevel@tonic-gate S [[!]pat] List subroutine names [not] matching pattern 176*0Sstevel@tonic-gate V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern. 177*0Sstevel@tonic-gate X [Vars] Same as "V current_package [Vars]". 178*0Sstevel@tonic-gate y [n [Vars]] List lexicals in higher scope <n>. Vars same as V. 179*0Sstevel@tonic-gate For more help, type h cmd_letter, or run man perldebug for all docs. 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gateMore confusing options than you can shake a big stick at! It's not as bad as 182*0Sstevel@tonic-gateit looks and it's very useful to know more about all of it, and fun too! 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gateThere's a couple of useful ones to know about straight away. You wouldn't 185*0Sstevel@tonic-gatethink we're using any libraries at all at the moment, but 'B<M>' will show 186*0Sstevel@tonic-gatewhich modules are currently loaded, and their version number, while 'B<m>' 187*0Sstevel@tonic-gatewill show the methods, and 'B<S>' shows all subroutines (by pattern) as 188*0Sstevel@tonic-gateshown below. 'B<V>' and 'B<X>' show variables in the program by package 189*0Sstevel@tonic-gatescope and can be constrained by pattern. 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate DB<2>S str 192*0Sstevel@tonic-gate dumpvar::stringify 193*0Sstevel@tonic-gate strict::bits 194*0Sstevel@tonic-gate strict::import 195*0Sstevel@tonic-gate strict::unimport 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gateUsing 'X' and cousins requires you not to use the type identifiers ($@%), just 198*0Sstevel@tonic-gatethe 'name': 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate DM<3>X ~err 201*0Sstevel@tonic-gate FileHandle(stderr) => fileno(2) 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gateRemember we're in our tiny program with a problem, we should have a look at 204*0Sstevel@tonic-gatewhere we are, and what our data looks like. First of all let's view some code 205*0Sstevel@tonic-gateat our present position (the first line of code in this case), via 'B<v>': 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate DB<4> v 208*0Sstevel@tonic-gate 1 #!/usr/bin/perl 209*0Sstevel@tonic-gate 2: use strict; 210*0Sstevel@tonic-gate 3 211*0Sstevel@tonic-gate 4==> my $key = 'welcome'; 212*0Sstevel@tonic-gate 5: my %data = ( 213*0Sstevel@tonic-gate 6 'this' => qw(that), 214*0Sstevel@tonic-gate 7 'tom' => qw(and jerry), 215*0Sstevel@tonic-gate 8 'welcome' => q(Hello World), 216*0Sstevel@tonic-gate 9 'zip' => q(welcome), 217*0Sstevel@tonic-gate 10 ); 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gateAt line number 4 is a helpful pointer, that tells you where you are now. To 220*0Sstevel@tonic-gatesee more code, type 'v' again: 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate DB<4> v 223*0Sstevel@tonic-gate 8 'welcome' => q(Hello World), 224*0Sstevel@tonic-gate 9 'zip' => q(welcome), 225*0Sstevel@tonic-gate 10 ); 226*0Sstevel@tonic-gate 11: my @data = keys %data; 227*0Sstevel@tonic-gate 12: print "All OK\n" if grep($key, keys %data); 228*0Sstevel@tonic-gate 13: print "$data{$key}\n"; 229*0Sstevel@tonic-gate 14: print "done: '$data{$key}'\n"; 230*0Sstevel@tonic-gate 15: exit; 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gateAnd if you wanted to list line 5 again, type 'l 5', (note the space): 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate DB<4> l 5 235*0Sstevel@tonic-gate 5: my %data = ( 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gateIn this case, there's not much to see, but of course normally there's pages of 238*0Sstevel@tonic-gatestuff to wade through, and 'l' can be very useful. To reset your view to the 239*0Sstevel@tonic-gateline we're about to execute, type a lone period '.': 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate DB<5> . 242*0Sstevel@tonic-gate main::(./data_a:4): my $key = 'welcome'; 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gateThe line shown is the one that is about to be executed B<next>, it hasn't 245*0Sstevel@tonic-gatehappened yet. So while we can print a variable with the letter 'B<p>', at 246*0Sstevel@tonic-gatethis point all we'd get is an empty (undefined) value back. What we need to 247*0Sstevel@tonic-gatedo is to step through the next executable statement with an 'B<s>': 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate DB<6> s 250*0Sstevel@tonic-gate main::(./data_a:5): my %data = ( 251*0Sstevel@tonic-gate main::(./data_a:6): 'this' => qw(that), 252*0Sstevel@tonic-gate main::(./data_a:7): 'tom' => qw(and jerry), 253*0Sstevel@tonic-gate main::(./data_a:8): 'welcome' => q(Hello World), 254*0Sstevel@tonic-gate main::(./data_a:9): 'zip' => q(welcome), 255*0Sstevel@tonic-gate main::(./data_a:10): ); 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gateNow we can have a look at that first ($key) variable: 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate DB<7> p $key 260*0Sstevel@tonic-gate welcome 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gateline 13 is where the action is, so let's continue down to there via the letter 263*0Sstevel@tonic-gate'B<c>', which by the way, inserts a 'one-time-only' breakpoint at the given 264*0Sstevel@tonic-gateline or sub routine: 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate DB<8> c 13 267*0Sstevel@tonic-gate All OK 268*0Sstevel@tonic-gate main::(./data_a:13): print "$data{$key}\n"; 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gateWe've gone past our check (where 'All OK' was printed) and have stopped just 271*0Sstevel@tonic-gatebefore the meat of our task. We could try to print out a couple of variables 272*0Sstevel@tonic-gateto see what is happening: 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate DB<9> p $data{$key} 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gateNot much in there, lets have a look at our hash: 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate DB<10> p %data 279*0Sstevel@tonic-gate Hello Worldziptomandwelcomejerrywelcomethisthat 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gate DB<11> p keys %data 282*0Sstevel@tonic-gate Hello Worldtomwelcomejerrythis 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gateWell, this isn't very easy to read, and using the helpful manual (B<h h>), the 285*0Sstevel@tonic-gate'B<x>' command looks promising: 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate DB<12> x %data 288*0Sstevel@tonic-gate 0 'Hello World' 289*0Sstevel@tonic-gate 1 'zip' 290*0Sstevel@tonic-gate 2 'tom' 291*0Sstevel@tonic-gate 3 'and' 292*0Sstevel@tonic-gate 4 'welcome' 293*0Sstevel@tonic-gate 5 undef 294*0Sstevel@tonic-gate 6 'jerry' 295*0Sstevel@tonic-gate 7 'welcome' 296*0Sstevel@tonic-gate 8 'this' 297*0Sstevel@tonic-gate 9 'that' 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gateThat's not much help, a couple of welcomes in there, but no indication of 300*0Sstevel@tonic-gatewhich are keys, and which are values, it's just a listed array dump and, in 301*0Sstevel@tonic-gatethis case, not particularly helpful. The trick here, is to use a B<reference> 302*0Sstevel@tonic-gateto the data structure: 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate DB<13> x \%data 305*0Sstevel@tonic-gate 0 HASH(0x8194bc4) 306*0Sstevel@tonic-gate 'Hello World' => 'zip' 307*0Sstevel@tonic-gate 'jerry' => 'welcome' 308*0Sstevel@tonic-gate 'this' => 'that' 309*0Sstevel@tonic-gate 'tom' => 'and' 310*0Sstevel@tonic-gate 'welcome' => undef 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gateThe reference is truly dumped and we can finally see what we're dealing with. 313*0Sstevel@tonic-gateOur quoting was perfectly valid but wrong for our purposes, with 'and jerry' 314*0Sstevel@tonic-gatebeing treated as 2 separate words rather than a phrase, thus throwing the 315*0Sstevel@tonic-gateevenly paired hash structure out of alignment. 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gateThe 'B<-w>' switch would have told us about this, had we used it at the start, 318*0Sstevel@tonic-gateand saved us a lot of trouble: 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate > perl -w data 321*0Sstevel@tonic-gate Odd number of elements in hash assignment at ./data line 5. 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gateWe fix our quoting: 'tom' => q(and jerry), and run it again, this time we get 324*0Sstevel@tonic-gateour expected output: 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate > perl -w data 327*0Sstevel@tonic-gate Hello World 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gateWhile we're here, take a closer look at the 'B<x>' command, it's really useful 331*0Sstevel@tonic-gateand will merrily dump out nested references, complete objects, partial objects 332*0Sstevel@tonic-gate- just about whatever you throw at it: 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gateLet's make a quick object and x-plode it, first we'll start the debugger: 335*0Sstevel@tonic-gateit wants some form of input from STDIN, so we give it something non-commital, 336*0Sstevel@tonic-gatea zero: 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate > perl -de 0 339*0Sstevel@tonic-gate Default die handler restored. 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate Loading DB routines from perl5db.pl version 1.07 342*0Sstevel@tonic-gate Editor support available. 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate Enter h or `h h' for help, or `man perldebug' for more help. 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate main::(-e:1): 0 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gateNow build an on-the-fly object over a couple of lines (note the backslash): 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate DB<1> $obj = bless({'unique_id'=>'123', 'attr'=> \ 351*0Sstevel@tonic-gate cont: {'col' => 'black', 'things' => [qw(this that etc)]}}, 'MY_class') 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gateAnd let's have a look at it: 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate DB<2> x $obj 356*0Sstevel@tonic-gate 0 MY_class=HASH(0x828ad98) 357*0Sstevel@tonic-gate 'attr' => HASH(0x828ad68) 358*0Sstevel@tonic-gate 'col' => 'black' 359*0Sstevel@tonic-gate 'things' => ARRAY(0x828abb8) 360*0Sstevel@tonic-gate 0 'this' 361*0Sstevel@tonic-gate 1 'that' 362*0Sstevel@tonic-gate 2 'etc' 363*0Sstevel@tonic-gate 'unique_id' => 123 364*0Sstevel@tonic-gate DB<3> 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gateUseful, huh? You can eval nearly anything in there, and experiment with bits 367*0Sstevel@tonic-gateof code or regexes until the cows come home: 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate DB<3> @data = qw(this that the other atheism leather theory scythe) 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate DB<4> p 'saw -> '.($cnt += map { print "\t:\t$_\n" } grep(/the/, sort @data)) 372*0Sstevel@tonic-gate atheism 373*0Sstevel@tonic-gate leather 374*0Sstevel@tonic-gate other 375*0Sstevel@tonic-gate scythe 376*0Sstevel@tonic-gate the 377*0Sstevel@tonic-gate theory 378*0Sstevel@tonic-gate saw -> 6 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gateIf you want to see the command History, type an 'B<H>': 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate DB<5> H 383*0Sstevel@tonic-gate 4: p 'saw -> '.($cnt += map { print "\t:\t$_\n" } grep(/the/, sort @data)) 384*0Sstevel@tonic-gate 3: @data = qw(this that the other atheism leather theory scythe) 385*0Sstevel@tonic-gate 2: x $obj 386*0Sstevel@tonic-gate 1: $obj = bless({'unique_id'=>'123', 'attr'=> 387*0Sstevel@tonic-gate {'col' => 'black', 'things' => [qw(this that etc)]}}, 'MY_class') 388*0Sstevel@tonic-gate DB<5> 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gateAnd if you want to repeat any previous command, use the exclamation: 'B<!>': 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate DB<5> !4 393*0Sstevel@tonic-gate p 'saw -> '.($cnt += map { print "$_\n" } grep(/the/, sort @data)) 394*0Sstevel@tonic-gate atheism 395*0Sstevel@tonic-gate leather 396*0Sstevel@tonic-gate other 397*0Sstevel@tonic-gate scythe 398*0Sstevel@tonic-gate the 399*0Sstevel@tonic-gate theory 400*0Sstevel@tonic-gate saw -> 12 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gateFor more on references see L<perlref> and L<perlreftut> 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate=head1 Stepping through code 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gateHere's a simple program which converts between Celsius and Fahrenheit, it too 408*0Sstevel@tonic-gatehas a problem: 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate #!/usr/bin/perl -w 411*0Sstevel@tonic-gate use strict; 412*0Sstevel@tonic-gate 413*0Sstevel@tonic-gate my $arg = $ARGV[0] || '-c20'; 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate if ($arg =~ /^\-(c|f)((\-|\+)*\d+(\.\d+)*)$/) { 416*0Sstevel@tonic-gate my ($deg, $num) = ($1, $2); 417*0Sstevel@tonic-gate my ($in, $out) = ($num, $num); 418*0Sstevel@tonic-gate if ($deg eq 'c') { 419*0Sstevel@tonic-gate $deg = 'f'; 420*0Sstevel@tonic-gate $out = &c2f($num); 421*0Sstevel@tonic-gate } else { 422*0Sstevel@tonic-gate $deg = 'c'; 423*0Sstevel@tonic-gate $out = &f2c($num); 424*0Sstevel@tonic-gate } 425*0Sstevel@tonic-gate $out = sprintf('%0.2f', $out); 426*0Sstevel@tonic-gate $out =~ s/^((\-|\+)*\d+)\.0+$/$1/; 427*0Sstevel@tonic-gate print "$out $deg\n"; 428*0Sstevel@tonic-gate } else { 429*0Sstevel@tonic-gate print "Usage: $0 -[c|f] num\n"; 430*0Sstevel@tonic-gate } 431*0Sstevel@tonic-gate exit; 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate sub f2c { 434*0Sstevel@tonic-gate my $f = shift; 435*0Sstevel@tonic-gate my $c = 5 * $f - 32 / 9; 436*0Sstevel@tonic-gate return $c; 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate sub c2f { 440*0Sstevel@tonic-gate my $c = shift; 441*0Sstevel@tonic-gate my $f = 9 * $c / 5 + 32; 442*0Sstevel@tonic-gate return $f; 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gateFor some reason, the Fahrenheit to Celsius conversion fails to return the 447*0Sstevel@tonic-gateexpected output. This is what it does: 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate > temp -c0.72 450*0Sstevel@tonic-gate 33.30 f 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate > temp -f33.3 453*0Sstevel@tonic-gate 162.94 c 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gateNot very consistent! We'll set a breakpoint in the code manually and run it 456*0Sstevel@tonic-gateunder the debugger to see what's going on. A breakpoint is a flag, to which 457*0Sstevel@tonic-gatethe debugger will run without interruption, when it reaches the breakpoint, it 458*0Sstevel@tonic-gatewill stop execution and offer a prompt for further interaction. In normal 459*0Sstevel@tonic-gateuse, these debugger commands are completely ignored, and they are safe - if a 460*0Sstevel@tonic-gatelittle messy, to leave in production code. 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate my ($in, $out) = ($num, $num); 463*0Sstevel@tonic-gate $DB::single=2; # insert at line 9! 464*0Sstevel@tonic-gate if ($deg eq 'c') 465*0Sstevel@tonic-gate ... 466*0Sstevel@tonic-gate 467*0Sstevel@tonic-gate > perl -d temp -f33.3 468*0Sstevel@tonic-gate Default die handler restored. 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate Loading DB routines from perl5db.pl version 1.07 471*0Sstevel@tonic-gate Editor support available. 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate Enter h or `h h' for help, or `man perldebug' for more help. 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate main::(temp:4): my $arg = $ARGV[0] || '-c100'; 476*0Sstevel@tonic-gate 477*0Sstevel@tonic-gateWe'll simply continue down to our pre-set breakpoint with a 'B<c>': 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate DB<1> c 480*0Sstevel@tonic-gate main::(temp:10): if ($deg eq 'c') { 481*0Sstevel@tonic-gate 482*0Sstevel@tonic-gateFollowed by a view command to see where we are: 483*0Sstevel@tonic-gate 484*0Sstevel@tonic-gate DB<1> v 485*0Sstevel@tonic-gate 7: my ($deg, $num) = ($1, $2); 486*0Sstevel@tonic-gate 8: my ($in, $out) = ($num, $num); 487*0Sstevel@tonic-gate 9: $DB::single=2; 488*0Sstevel@tonic-gate 10==> if ($deg eq 'c') { 489*0Sstevel@tonic-gate 11: $deg = 'f'; 490*0Sstevel@tonic-gate 12: $out = &c2f($num); 491*0Sstevel@tonic-gate 13 } else { 492*0Sstevel@tonic-gate 14: $deg = 'c'; 493*0Sstevel@tonic-gate 15: $out = &f2c($num); 494*0Sstevel@tonic-gate 16 } 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gateAnd a print to show what values we're currently using: 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate DB<1> p $deg, $num 499*0Sstevel@tonic-gate f33.3 500*0Sstevel@tonic-gate 501*0Sstevel@tonic-gateWe can put another break point on any line beginning with a colon, we'll use 502*0Sstevel@tonic-gateline 17 as that's just as we come out of the subroutine, and we'd like to 503*0Sstevel@tonic-gatepause there later on: 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate DB<2> b 17 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gateThere's no feedback from this, but you can see what breakpoints are set by 508*0Sstevel@tonic-gateusing the list 'L' command: 509*0Sstevel@tonic-gate 510*0Sstevel@tonic-gate DB<3> L 511*0Sstevel@tonic-gate temp: 512*0Sstevel@tonic-gate 17: print "$out $deg\n"; 513*0Sstevel@tonic-gate break if (1) 514*0Sstevel@tonic-gate 515*0Sstevel@tonic-gateNote that to delete a breakpoint you use 'd' or 'D'. 516*0Sstevel@tonic-gate 517*0Sstevel@tonic-gateNow we'll continue down into our subroutine, this time rather than by line 518*0Sstevel@tonic-gatenumber, we'll use the subroutine name, followed by the now familiar 'v': 519*0Sstevel@tonic-gate 520*0Sstevel@tonic-gate DB<3> c f2c 521*0Sstevel@tonic-gate main::f2c(temp:30): my $f = shift; 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate DB<4> v 524*0Sstevel@tonic-gate 24: exit; 525*0Sstevel@tonic-gate 25 526*0Sstevel@tonic-gate 26 sub f2c { 527*0Sstevel@tonic-gate 27==> my $f = shift; 528*0Sstevel@tonic-gate 28: my $c = 5 * $f - 32 / 9; 529*0Sstevel@tonic-gate 29: return $c; 530*0Sstevel@tonic-gate 30 } 531*0Sstevel@tonic-gate 31 532*0Sstevel@tonic-gate 32 sub c2f { 533*0Sstevel@tonic-gate 33: my $c = shift; 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gateNote that if there was a subroutine call between us and line 29, and we wanted 537*0Sstevel@tonic-gateto B<single-step> through it, we could use the 'B<s>' command, and to step 538*0Sstevel@tonic-gateover it we would use 'B<n>' which would execute the sub, but not descend into 539*0Sstevel@tonic-gateit for inspection. In this case though, we simply continue down to line 29: 540*0Sstevel@tonic-gate 541*0Sstevel@tonic-gate DB<4> c 29 542*0Sstevel@tonic-gate main::f2c(temp:29): return $c; 543*0Sstevel@tonic-gate 544*0Sstevel@tonic-gateAnd have a look at the return value: 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gate DB<5> p $c 547*0Sstevel@tonic-gate 162.944444444444 548*0Sstevel@tonic-gate 549*0Sstevel@tonic-gateThis is not the right answer at all, but the sum looks correct. I wonder if 550*0Sstevel@tonic-gateit's anything to do with operator precedence? We'll try a couple of other 551*0Sstevel@tonic-gatepossibilities with our sum: 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate DB<6> p (5 * $f - 32 / 9) 554*0Sstevel@tonic-gate 162.944444444444 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate DB<7> p 5 * $f - (32 / 9) 557*0Sstevel@tonic-gate 162.944444444444 558*0Sstevel@tonic-gate 559*0Sstevel@tonic-gate DB<8> p (5 * $f) - 32 / 9 560*0Sstevel@tonic-gate 162.944444444444 561*0Sstevel@tonic-gate 562*0Sstevel@tonic-gate DB<9> p 5 * ($f - 32) / 9 563*0Sstevel@tonic-gate 0.722222222222221 564*0Sstevel@tonic-gate 565*0Sstevel@tonic-gate:-) that's more like it! Ok, now we can set our return variable and we'll 566*0Sstevel@tonic-gatereturn out of the sub with an 'r': 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate DB<10> $c = 5 * ($f - 32) / 9 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate DB<11> r 571*0Sstevel@tonic-gate scalar context return from main::f2c: 0.722222222222221 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gateLooks good, let's just continue off the end of the script: 574*0Sstevel@tonic-gate 575*0Sstevel@tonic-gate DB<12> c 576*0Sstevel@tonic-gate 0.72 c 577*0Sstevel@tonic-gate Debugged program terminated. Use q to quit or R to restart, 578*0Sstevel@tonic-gate use O inhibit_exit to avoid stopping after program termination, 579*0Sstevel@tonic-gate h q, h R or h O to get additional info. 580*0Sstevel@tonic-gate 581*0Sstevel@tonic-gateA quick fix to the offending line (insert the missing parentheses) in the 582*0Sstevel@tonic-gateactual program and we're finished. 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate 585*0Sstevel@tonic-gate=head1 Placeholder for a, w, t, T 586*0Sstevel@tonic-gate 587*0Sstevel@tonic-gateActions, watch variables, stack traces etc.: on the TODO list. 588*0Sstevel@tonic-gate 589*0Sstevel@tonic-gate a 590*0Sstevel@tonic-gate 591*0Sstevel@tonic-gate w 592*0Sstevel@tonic-gate 593*0Sstevel@tonic-gate t 594*0Sstevel@tonic-gate 595*0Sstevel@tonic-gate T 596*0Sstevel@tonic-gate 597*0Sstevel@tonic-gate 598*0Sstevel@tonic-gate=head1 REGULAR EXPRESSIONS 599*0Sstevel@tonic-gate 600*0Sstevel@tonic-gateEver wanted to know what a regex looked like? You'll need perl compiled with 601*0Sstevel@tonic-gatethe DEBUGGING flag for this one: 602*0Sstevel@tonic-gate 603*0Sstevel@tonic-gate > perl -Dr -e '/^pe(a)*rl$/i' 604*0Sstevel@tonic-gate Compiling REx `^pe(a)*rl$' 605*0Sstevel@tonic-gate size 17 first at 2 606*0Sstevel@tonic-gate rarest char 607*0Sstevel@tonic-gate at 0 608*0Sstevel@tonic-gate 1: BOL(2) 609*0Sstevel@tonic-gate 2: EXACTF <pe>(4) 610*0Sstevel@tonic-gate 4: CURLYN[1] {0,32767}(14) 611*0Sstevel@tonic-gate 6: NOTHING(8) 612*0Sstevel@tonic-gate 8: EXACTF <a>(0) 613*0Sstevel@tonic-gate 12: WHILEM(0) 614*0Sstevel@tonic-gate 13: NOTHING(14) 615*0Sstevel@tonic-gate 14: EXACTF <rl>(16) 616*0Sstevel@tonic-gate 16: EOL(17) 617*0Sstevel@tonic-gate 17: END(0) 618*0Sstevel@tonic-gate floating `'$ at 4..2147483647 (checking floating) stclass `EXACTF <pe>' 619*0Sstevel@tonic-gateanchored(BOL) minlen 4 620*0Sstevel@tonic-gate Omitting $` $& $' support. 621*0Sstevel@tonic-gate 622*0Sstevel@tonic-gate EXECUTING... 623*0Sstevel@tonic-gate 624*0Sstevel@tonic-gate Freeing REx: `^pe(a)*rl$' 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gateDid you really want to know? :-) 627*0Sstevel@tonic-gateFor more gory details on getting regular expressions to work, have a look at 628*0Sstevel@tonic-gateL<perlre>, L<perlretut>, and to decode the mysterious labels (BOL and CURLYN, 629*0Sstevel@tonic-gateetc. above), see L<perldebguts>. 630*0Sstevel@tonic-gate 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate=head1 OUTPUT TIPS 633*0Sstevel@tonic-gate 634*0Sstevel@tonic-gateTo get all the output from your error log, and not miss any messages via 635*0Sstevel@tonic-gatehelpful operating system buffering, insert a line like this, at the start of 636*0Sstevel@tonic-gateyour script: 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gate $|=1; 639*0Sstevel@tonic-gate 640*0Sstevel@tonic-gateTo watch the tail of a dynamically growing logfile, (from the command line): 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate tail -f $error_log 643*0Sstevel@tonic-gate 644*0Sstevel@tonic-gateWrapping all die calls in a handler routine can be useful to see how, and from 645*0Sstevel@tonic-gatewhere, they're being called, L<perlvar> has more information: 646*0Sstevel@tonic-gate 647*0Sstevel@tonic-gate BEGIN { $SIG{__DIE__} = sub { require Carp; Carp::confess(@_) } } 648*0Sstevel@tonic-gate 649*0Sstevel@tonic-gateVarious useful techniques for the redirection of STDOUT and STDERR filehandles 650*0Sstevel@tonic-gateare explained in L<perlopentut> and L<perlfaq8>. 651*0Sstevel@tonic-gate 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate=head1 CGI 654*0Sstevel@tonic-gate 655*0Sstevel@tonic-gateJust a quick hint here for all those CGI programmers who can't figure out how 656*0Sstevel@tonic-gateon earth to get past that 'waiting for input' prompt, when running their CGI 657*0Sstevel@tonic-gatescript from the command-line, try something like this: 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate > perl -d my_cgi.pl -nodebug 660*0Sstevel@tonic-gate 661*0Sstevel@tonic-gateOf course L<CGI> and L<perlfaq9> will tell you more. 662*0Sstevel@tonic-gate 663*0Sstevel@tonic-gate 664*0Sstevel@tonic-gate=head1 GUIs 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gateThe command line interface is tightly integrated with an B<emacs> extension 667*0Sstevel@tonic-gateand there's a B<vi> interface too. 668*0Sstevel@tonic-gate 669*0Sstevel@tonic-gateYou don't have to do this all on the command line, though, there are a few GUI 670*0Sstevel@tonic-gateoptions out there. The nice thing about these is you can wave a mouse over a 671*0Sstevel@tonic-gatevariable and a dump of its data will appear in an appropriate window, or in a 672*0Sstevel@tonic-gatepopup balloon, no more tiresome typing of 'x $varname' :-) 673*0Sstevel@tonic-gate 674*0Sstevel@tonic-gateIn particular have a hunt around for the following: 675*0Sstevel@tonic-gate 676*0Sstevel@tonic-gateB<ptkdb> perlTK based wrapper for the built-in debugger 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gateB<ddd> data display debugger 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gateB<PerlDevKit> and B<PerlBuilder> are NT specific 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gateNB. (more info on these and others would be appreciated). 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate 685*0Sstevel@tonic-gate=head1 SUMMARY 686*0Sstevel@tonic-gate 687*0Sstevel@tonic-gateWe've seen how to encourage good coding practices with B<use strict> and 688*0Sstevel@tonic-gateB<-w>. We can run the perl debugger B<perl -d scriptname> to inspect your 689*0Sstevel@tonic-gatedata from within the perl debugger with the B<p> and B<x> commands. You can 690*0Sstevel@tonic-gatewalk through your code, set breakpoints with B<b> and step through that code 691*0Sstevel@tonic-gatewith B<s> or B<n>, continue with B<c> and return from a sub with B<r>. Fairly 692*0Sstevel@tonic-gateintuitive stuff when you get down to it. 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gateThere is of course lots more to find out about, this has just scratched the 695*0Sstevel@tonic-gatesurface. The best way to learn more is to use perldoc to find out more about 696*0Sstevel@tonic-gatethe language, to read the on-line help (L<perldebug> is probably the next 697*0Sstevel@tonic-gateplace to go), and of course, experiment. 698*0Sstevel@tonic-gate 699*0Sstevel@tonic-gate 700*0Sstevel@tonic-gate=head1 SEE ALSO 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gateL<perldebug>, 703*0Sstevel@tonic-gateL<perldebguts>, 704*0Sstevel@tonic-gateL<perldiag>, 705*0Sstevel@tonic-gateL<dprofpp>, 706*0Sstevel@tonic-gateL<perlrun> 707*0Sstevel@tonic-gate 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate=head1 AUTHOR 710*0Sstevel@tonic-gate 711*0Sstevel@tonic-gateRichard Foley <richard@rfi.net> Copyright (c) 2000 712*0Sstevel@tonic-gate 713*0Sstevel@tonic-gate 714*0Sstevel@tonic-gate=head1 CONTRIBUTORS 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gateVarious people have made helpful suggestions and contributions, in particular: 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gateRonald J Kimball <rjk@linguist.dartmouth.edu> 719*0Sstevel@tonic-gate 720*0Sstevel@tonic-gateHugo van der Sanden <hv@crypt0.demon.co.uk> 721*0Sstevel@tonic-gate 722*0Sstevel@tonic-gatePeter Scott <Peter@PSDT.com> 723*0Sstevel@tonic-gate 724