So someone on FWP brought up using B::Deparse to display the contents
of subroutine references.  This, plus the fact that I found myself
needing multi-line assertions drove me to write this new function for
Carp::Assert.  

I'm looking for comments before I release this in the new version.


=item B<affirm>

    affirm BLOCK if DEBUG;
    affirm BLOCK $name if DEBUG;

Very similar to assert(), but instead of taking just a simple
expression it takes an entire block of code and evaluates it to make
sure its true.  This can allow more complicated assertions than
assert() can without letting the debugging code leak out into
production and without having to smash together several
statements into one.

    affirm {
        my $customer = Customer->new($customerid);
        my @cards = $customer->credit_cards;
        grep { $_->is_active } @cards;
    } "Our customer has an active credit card";

affirm() also has the nice side effect that if you forgot the C<if DEBUG>
suffix its arguments will not be evaluated at all.  This can be nice
if you stick affirm()s with expensive checks into hot loops and other
time-sensitive parts of your program.

If you have B::Deparse installed and do not give a $name to your
affirmation, affirm() will use that to report what failed:

    Assertion ({
        my $customer = Customer->new($customerid);
        my @cards = $customer->credit_cards;
        grep { $_->is_active } @cards;
    }) failed!

=cut

sub affirm (&;$) {
    unless( eval { &{$_[0]}; } ) {
        my $name = $_[1];
        if( !defined $name and eval { require B::Deparse } ) {
            $name = B::Deparse->new->coderef2text($_[0]);
        }
        require Carp;
        Carp::confess( _fail_msg($name) );
    }
    return undef;
}


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>    http://www.pobox.com/~schwern/
Perl6 Quality Assurance     <[EMAIL PROTECTED]>       Kwalitee Is Job One
If you have to shoot, shoot!  Don't talk.
                -- Tuco, "The Good, The Bad And The Ugly"

Reply via email to