Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

debugging /logging help

by boo_radley (Parson)
on Dec 07, 2000 at 00:25 UTC ( [id://45307]=perlquestion: print w/replies, xml ) Need Help??

boo_radley has asked for the wisdom of the Perl Monks concerning the following question:

So I'm writing a mildly complex program, and I want to print out some flow information in a few places. I whomped up the following
sub debugprint { if (defined ($DEBUG)) {print scalar localtime , " : ", @_}; }
and would appreciate any thought's y'all might have. whenever I need to do some traces, I just change my $DEBUG; to my $DEBUG=1; I am aware of perl -d, but it's a little more than I need right now. I'm just interested in things like
debugprint ("Now entering mysub...\n"); debugprint ("parameters are @_\n");
etc. Comments?

Replies are listed 'Best First'.
Re: debugging /logging help
by dchetlin (Friar) on Dec 07, 2000 at 10:23 UTC
    A brief comment on efficiency:

    If you use constant subs instead of variables for toggling debugging, Perl is smart enough to compile them out of existence so when you go into production the debugging will have no adverse performance effects.

    You can observe this in action using B::Deparse:

    [~] $ perl -MO=Deparse -e'sub D(){0}print"foo"if D' sub D () { 0; } '???'; -e syntax OK [~] $ perl -MO=Deparse -e'sub D(){1}print"foo"if D' sub D () { 1; } print 'foo'; -e syntax OK

    The `???' in the first example means that Perl has optimized out whatever used to be there. And you'll note the lack of a conditional in the second example, which was also optimized out. Perl is smart enough to realize that a subroutine with no parameters can be computed at compile time, and so replaces all calls to D() with its actual value (0 or 1 depending on the example). Then the peephole optimizer realizes that the print statements depend on the conditionals, and since the value of the conditionals is known, eliminates them and leaves either nothing, in the case of D() == 0, or just the bare print, in the case of D() == 1.

    -dlc

Re: debugging /logging help
by a (Friar) on Dec 07, 2000 at 06:57 UTC
    One thing I've found useful in debugging is to use levels, e.g.:
    my $debug = 11; ... print STDERR "something worked: $wombat\n" if $debug > 5; ... print STDERR "in here: too much detail", join ", ", @_, "\n" if $debug > 20;
    etc. That way I can leave them in until production or later, and bump things back up when I break something. I try to make it a habit to always write debug noise in like that at the start (every "print STDERR ..." line has a debug level) and it works out much easier as the development progresses.

    You could add something like that:

    debugprint("now entering mysub ...\n", 11); sub debugprint($$) { my ($err_str, $debug_value) = @_; print $err_str if $debug_value >= $debug;
    or something ...

    a

      I use an approach along these lines, but break the printing out into a sub...

      And I have a question to contribute:
      Is there a way to tell on what line your sub was called from? So that I could include the current line number in the sub:

      sub mydebug { $msg = shift; print STDERR 'Line '. $linethatcalledme .": $msg\n"; }
      I've been inactively looking for this for a while, almost to the point that I'm going to have to start looking for real =)

      --Glenn

        Here's a good place to look for real: caller. :)

        Not only can caller tell you where your sub was called from, it can tell you where the sub that called your sub was called from, and so on all the way back to the main code.

Re: debugging /logging help
by quidity (Pilgrim) on Dec 07, 2000 at 00:31 UTC

    It is said that the best debugging aid is a set of liberally sprinkled print statements and some careful logical thought.

    I find it useful to give most of my larger programs a 'verbose' mode which prints out progress indication, time spent, contents of data structures and whatnot. The easiest way of doing so is to have a sub:

    sub debug_info { print join ':', "\n*", @_; print "\n"; return 1; }

    then throughout the program have lines like:

    debug_info('plotting world domination',$foo, $bar) if $verbose;

    I usually make a command line option for verbosity with something like:

    my $verbose = $ARGV[0] || 0;
      why not check your if $verbose value within your subroutine? That way you spend less time sprinkling "if $verbose" throughout your program.. Granted, my method is slightly less effecient, but you could change your sub to:
      sub debug_info { return(0) unless $verbose; print join ':', "\n*", @_; print "\n"; return 1; }


      -marius
Re: debugging /logging help
by gharris (Beadle) on Dec 07, 2000 at 23:00 UTC
    If you like to be able to log to different targets (screen/file/syslog/remote machine/etc...) there is a nice module on CPAN called Log::Dispatch that I've been playing with recently.
    It provides a consistent OO interface to logging to all kinds of different targets
    Here is the synopsis:
    use Log::Dispatch; my $dispatcher = Log::Dispatch->new; $dispatcher->add( Log::Dispatch::File->new( name => 'file1', min_level => 'debug', filename => 'logfile' ) ); $dispatcher->log( level => 'info', message => 'Blah, blah' ); my $sub = sub { my %p = @_; return reverse $p{message}; }; my $reversing_dispatcher = Log::Dispatch->new( callbacks => $sub );
    Hope that helps!

    --Glenn

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-24 13:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found