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

Debugging in packages

by agoth (Chaplain)
on Jul 17, 2001 at 17:18 UTC ( [id://97304]=perlquestion: print w/replies, xml ) Need Help??

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

I need to debug some code and the way I usually do it is by having statements such as print x if $DEBUG.

I've looked in perltoot and it recommends that you have debug methods, but I'd like to do this without having to have extra methods or to have to immplement get / set methods for my DEBUG flag, or to have to pass in extra parameters as I'll have to retro fit this across modules.

My solution is below, am I doing things that are not a good idea by explicitly setting $main::DEBUG or is this OK?

#------------- script #!/usr/local/bin/perl -w use strict; use Deb; $main::DEBUG = 1; my $db = new Deb; $db->start(); print "done \n"; #----------package #!/usr/local/bin/perl5 package Deb; use strict; sub new { my $class = shift; my $self = {}; $self->{DEBUG} = $main::DEBUG || 0; bless $self, $class; return $self; } sub start { my $self = shift; print "Debugging flag is working\n" if ($self->{DEBUG}); print "Debugging flag is working\n" if ($main::DEBUG); } 1;

Replies are listed 'Best First'.
Re: Debugging in packages
by TheoPetersen (Priest) on Jul 17, 2001 at 17:30 UTC
    There's nothing terribly wrong with this approach, and it's the typical first step along the way to more complicated debugging schemes. Once the script is working you'll probably go on to set the debug flag from an environment variable or command line option as I did.

    The reason for other recommendations is that this scheme makes debugging an all or nothing mechanism. When I was working on a very complex system with many classes, I needed a way to get run-time information from the classes of interest, without clogging output completely with the full range of feedback I'd coded into the system. For that I used an initialization that parsed out which classes should spit out run-time information, then went on the specialize it more so that the instances associated with certain tables would have debugging on, while others were off.

    One disadvantage to using a global variable is that it is prone to typos. If your code refers to $main::DEBYG somewhere you'll have to catch it yourself; it's a valid variable name.

    Also, you can shorten your modifiers:

    if $self->{DEBUG}
    rather than
    if ($self->{DEBUG})
    unless you just prefer the way the parenthesis look.
Re: Debugging in packages
by MZSanford (Curate) on Jul 17, 2001 at 17:38 UTC
    If this is in a module, i usually add a _debug key to my blessed hash and use a function with a name similar to dbg("Message"). All this function does is :
    sub dbg { my ($self,$msg) = @_; return if (! $self->{_debug}); print STDERR "[DEBUG] : $msg\n"; }
    And, a simple accessor method like :
    sub debug { my ($self,$val) = @_; $self->{_debug} = $val if (defined $val); $self->{_debug}; }
    While this all may seem a bit elaborate, it is excedingly useful to have as a standard for every module. If the $main::DEBUG is the approach you prefer, there is always more than one way to do it, and changing dbg to the following would work :
    sub dbg { my $msg = shift; print "[DEBUG] : $msg\n" if ($main::DEBUG); }

    OH, a sarcasm detector, that’s really useful
(tye)Re: Debugging in packages
by tye (Sage) on Jul 17, 2001 at 21:50 UTC

    You can do something like:

    package My::WunderCode; BEGIN { if( $ENV{DEBUG_MY_WUNDERCODE} ) { eval "sub debug() { !1 }"; } else { eval "sub debug() { 1 }"; } die $@ if $@; } warn "Debugging ",__PACKAGE__,"...\n" if debug;
    and Perl will optimize away your debug code when it is compiled if debugging is not enabled. Just another way...

            - tye (but my friends call me "Tye")
      Question... I am new to perl(about a month or so) and i have finished the Learning Perl for Win32...where else, in your opinion, should i go to further my learning for perl in retrospect to being able to apply it on my NT/2k machines. I bought "Windows NT - Win32 Perl Programming: The Standard Extensions" and it is a little more advanced in programming. Maybe i guess...i am looking for...something that will keep going in progression...kinda like how the Learning Perl book does...learn a little something new and test my knowledge on it with everything that i previously learned as well. I am able to apply scripts that i find or other people provide for me as examples by tweeking them, but i probably would not be able to get there by myself. Does that make sense? This may be a lot of jarble..but since you do program for NT/2k environment, i figured you would be a good person to ask. Any advice would be much appreciated. As i am always open to listen. thnx ~Ray
Re: Debugging in packages
by ariels (Curate) on Jul 17, 2001 at 17:38 UTC
    Depending on your needs, it may be better to use the global variable $main::DEBUG directly rather than a stored local copy such as $self->{DEBUG}. The reason is you might want to localise $main::DEBUG.

    That is, if package Deb prints reams of debugging information when $main::DEBUG is set, you might find it useful in debugging to say

    package Deb; sub frob { # do stuff... print_debugging_info if $main::DEBUG; # do more stuff... } # ... package main; $::DEBUG = undef; # usually don't want debugging information my $deb1 = new Deb (...); my $deb2 = new Deb (...); # do stuff with $deb1, $deb2, but no debugging information { local $::DEBUG = 1; # buggy bit $deb1->frob(42); $deb2->nitz(17); } # no more debugging output # ...

    local is usually a very good match for various logs.

Re: Debugging in packages
by clemburg (Curate) on Jul 17, 2001 at 17:55 UTC

    A better approach IMHO is to have a centralized messaging/logging/debugging method or function that takes a message and a priority number, and use that in your code instead of calling print().

    Then you can set the debugging level (e.g., with an environment variable, or a configuration option, or even just an option or an argument), and if the current debugging level exceeds or is equal to the priority number of a message, the message will be printed to STDERR, or logged to a file, or whatever.

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com

      I was looking at Devel::Messenger this morning. It looks like it does this. You can have debug levels and print certain messages only if debugging is on or above that level. It will print to files\filehandles as well. I haven't tried it yet though.

      Error: Keyboard not attached. Press F1 to continue.

        For production servers on Unix, a good idea is to use Sys::Syslog. On Windows, the equivalent would be Win32::EventLog.

        Christian Lemburg
        Brainbench MVP for Perl
        http://www.brainbench.com

Re: Debugging in packages
by Masem (Monsignor) on Jul 17, 2001 at 17:32 UTC
    I have found that most of the CPAN packages that provide debugging provide a special class global variable (by using Exporter or 'our') that enabled debugging in the class. While DEBUG is a sufficiently common variable that people will set if they want to debug something, you can't guarentee it, and it's better if your class provides it's own way to do it.


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2024-04-25 11:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found