Debugging Methods

It's common for a class to have a debugging mechanism. For example, you might want to see when objects are created or destroyed. To do that, add a debugging variable as a file-scoped lexical. For this, we'll pull in the standard Carp module to emit our warnings and fatal messages. That way messages will come out with the caller's filename and line number instead of our own; if we wanted them to be from our own perspective, we'd just use die and warn directly instead of croak and carp respectively.

    use Carp;
    my $Debugging = 0;

Now add a new class method to access the variable.

    sub debug {
        my $class = shift;
        if (ref $class)  { confess "Class method called as object method" }
        unless (@_ == 1) { confess "usage: CLASSNAME->debug(level)" }
        $Debugging = shift;
    }

Now fix up DESTROY to murmur a bit as the moribund object expires:

    sub DESTROY {
        my $self = shift;
        if ($Debugging) { carp "Destroying $self " . $self->name }
        -- ${ $self->{"_CENSUS"} };
    }

One could conceivably make a per-object debug state. That way you could call both of these:

    Person->debug(1);   # entire class
    $him->debug(1);     # just this object

To do so, we need our debugging method to be a ``bimodal'' one, one that works on both classes and objects. Therefore, adjust the debug and DESTROY methods as follows:

    sub debug {
        my $self = shift;
        confess "usage: thing->debug(level)"    unless @_ == 1;
        my $level = shift;
        if (ref($self))  {
            $self->{"_DEBUG"} = $level;		# just myself
        } else {
            $Debugging        = $level;         # whole class
        }
    }

    sub DESTROY {
        my $self = shift;
        if ($Debugging || $self->{"_DEBUG"}) {
            carp "Destroying $self " . $self->name;
        }
        -- ${ $self->{"_CENSUS"} };
    }

What happens if a derived class (which we'll call Employee) inherits methods from this Person base class? Then Employee->debug, when called as a class method, manipulates $Person::Debugging not $Employee::Debugging.