Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Easy, elemental, but cool debug trick.

by jjhorner (Hermit)
on May 24, 2000 at 21:17 UTC ( [id://14606]=perlmeditation: print w/replies, xml ) Need Help??

I have a co-worker who is a long-time C coder. He showed me a trick that I should have thought of a long time ago, but never occurred to me.

I use it often now and it simplifies things greatly.

At the head of a script, I add the line:

my $DEBUG = 1;

and after a variable should gain a new value, I add:

print $variable if $DEBUG;

This helps me make sure my variables are given the values that I want. When I want the text to run without the extra mess, I change $DEBUG to 0.

Anyone else have any neat practices that keep them honest, besides using 'strict' or '-w'?

JJ

Replies are listed 'Best First'.
(jcwren) RE: Easy, elemental, but cool debug trick.
by jcwren (Prior) on May 25, 2000 at 00:06 UTC
    I use a similiar technique. When debugging a CGI application, however, prints can really mess you up.

    For that situation, I have a routine (below) that writes to a file. It accepts two parameters, one which is a class string, and a message string. The section string allows me to put messages in a arbitrary category (say, 'debug', 'authentication', or 'SQL'), and the text to be printed.

    Each message is timestamped, and also stamped with a user ID (that's internal to me application, and could be ignored).

    I also have a similiar version that use the syslog facility to write /var/log/messages.

    sub debug_log { @_ == 2 or confess "Incorrect number of arguments"; my ($section, $action) = @_; my $userid = 0; my $string = 0; $userid = $globalUserID || "<nobody>"; $string = sprintf ("%s %s %s:%s\n", scalar localtime, $userid, $sec +tion, $action); open (SINK, ">> /home/httpd/somedir/logfile") or confess "Can't ope +n logfile"; print SINK $string; close (SINK) or confess "Can't close logfile"; }
      Just always use warn "foobar" if $DEBUG instead of print, then it will do the right thingtm under both mod_cgi and mod_perl. For logging you should take a look at the Log::Agent module available on CPAN.
RE: Easy, elemental, but cool debug trick.
by KM (Priest) on May 24, 2000 at 21:23 UTC
    I usually do what you showed above. Sometimes I do:

    sub DEBUG () { 1 }

    If I have many statements in there doing ... if $DEBUG.

    I also use perl -c, the debugger, and whenever I am doing CGI I like to use CGI::Carp qw(fatalsToBrowser). I also use -T, but that isn't really a debugging thing.

    Cheers,
    KM

RE: Easy, elemental, but cool debug trick.
by Adam (Vicar) on May 24, 2000 at 21:30 UTC
    Yeah, this is a good practice but adds an extra branch for every debug check. When I do this in C++ I use compiler directives to remove my debug code so that I don't bog down the final product. I wonder if Perl is smart enough to optimize out those branches when it compiles? This is more likely with KM's technique because Perl will inline the constant function.
      Perl has a command-line flag, -P (capital P), which sends its input script through the C pre-processor before perl compilation. I can't recall ever hearing of anybody actually using it, though it's obviously there for a reason, and this sounds like as good a reason as any. (Note that perldoc perlrun warns, 'Because both comments and cpp directives begin with the # character, you should avoid starting comments with any words recognized by the C preprocessor such as "if", "else", or "define".' Also note that you can't define values on the command line; -D sets debugger flags.)
Re: Easy, elemental, but cool debug trick.
by link (Novice) on May 28, 2000 at 18:14 UTC
    Well, you might want to consider doing it with the constant pragma. use constant DEBUG => 1; I tend to alternate between that and simply testing $^W: print qq(\$foo is "$foo"\n) if $^W; IMO, -w should never be enabled in production code (except insofar as you think you might forget to reenable it when you start development again!) so this works well.
      2 comments. I use: $debug = 20; print "debug info here\n" if $debug > 5 print "even more info here\n" if $debug > 10 etc. which lets me turn on and off levels of debug during the process (e.g. subroutines can dump details or just announce their presence as they get 'better' throughout the scripting). I try to write these sorts of debug stmts at the beginning and leave them in (often for years ;-) as experience shows I'll need them later and often need to turn them back on or bump the levels back up as things change. The other thing I just saw was somebody wrote all there constant comparisons: if ( 6 == $value ) { ... claiming that this "catches" the missing "=" problem at compile time (can't do 6 = $value) w/o the -w. Not sure I believe its a good thing (ugly for one, reads wrong) and not sure '6' shouldn't be $value_if_this sort of constant somewhere (in most cases) but the fellow is very accomplished programmer so take it for what you will. a
RE: Easy, elemental, but cool debug trick.
by mattr (Curate) on Jun 11, 2000 at 15:05 UTC
    I usually set $debug at top of a perl program or if I am trying to make something useful, in a module which is included by several. ($debug=$GlobalConfig::debug)

    if ($debug>3) {print "Program Name: Error. $!";} ##DEBUG

    I use 0=normal, 1..5 for more and more detail up to full DBI negotiation, and unique negative number ranges for debugging special cases.

    This plus the block commenting code above seems useful. The worst thing I've had is a client that actually sent me back modified code (stripped out all my debugging and copyright info, also renaming the files, since their server couldn't handle something they had requested) and I had to take Ediff to it. You'd think the perl interpreter would not spend much time on testing the predefined constant..

    You can also print to STDERR which you should be able to catch live in another window by grep tail your.httpd.error.log otherwise you'll need to turn on/off httpd header print statements in your code to be able to catch early config errors. Maybe better to look at that log agent module or something spiffier for mod_perl segfault strangeness..

    Best regards,

    Matt

      Oh forgot to say that the same client was saved by my leaving the debugging statements intact, since after telling them to change $debug I was able to debug it remotely through my browser after they had installed it on their own server.
RE: Easy, elemental, but cool debug trick.
by Bourgeois_Rage (Beadle) on May 25, 2000 at 23:00 UTC
    Nice, I have similar techniques, but this one makes it real easy to clean up. I'll be sure to use this one. I think that if you write a short Perl program using REGEXP, you could scan through the document and remove all the lines with $DEBUG in it. That would seem to be the quickest way to clean up the file to me.
      Neat idea, but why remove them? I amlost always need to turn debugging back on sooner or later. How about something like this:
      perl -i.bak -e 's/^(.+\$DEBUG.+)$/#$1/' foo.pl
      to turn DEBUG off and then
      perl -i.bak -e 's/^#(.+\$DEBUG.+)$/$1/' foo.pl
      to turn it back on.

      At which point, do we even need to define a variable? As a convention, any debug code would simply need #DEBUG hanging off the end and simply change the \$DEBUG part of the regex to look for #DEBUG.

      Is it just me, or is there something very weird about using perl to preprocess perl?

      This waste of time has been gratefully brought to you by
      mikfire

        This is very neat. Going one step further, to allow debug blocks:
        perl -pi.bak -e 's/^(.*)$/#$1/ if /\bDEBUG\b/../\bENDDEBUG\b/' foo.pl
        to remove the block, and
        perl -pi.bak -e 's/^#(.*)$/$1/ if /\bDEBUG\b/../\bENDDEBUG\b/' foo.pl
        To reenable it. Then you can do something like this:
        ... code # DEBUG debug code # ENDDEBUG ... more code
        And yes, there is something very weird about using Perl to pre-process Perl...

        --ZZamboni

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://14606]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-03-28 16:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found