Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

How to lose Carp levels with @CARP_NOT?

by liz (Monsignor)
on Jan 28, 2004 at 21:08 UTC ( [id://324785]=perlquestion: print w/replies, xml ) Need Help??

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

While implementing a new Log::Dispatch output channel called Log::Dispatch::Perl (which is on its way to CPAN, but also available from http://www.liz.nl/CPAN/), I found that I cannot conveniently "lose" a number of levels of the message created by Carp::longmess, as seen if you do a Carp::confess.

The documentation says:

Packages claim that there won't be errors on calls to or from packages explicitly marked as safe by inclusion in @CARP_NOT, or (if that array is empty) @ISA.
Ok, so I added:
our @CARP_NOT = ('Log::Dispatch::Output','Log::Dispatch');
to my Log::Dispatch::Perl code. But a Carp::confess still lists levels with these modules:
use Log::Dispatch::Perl; my $dispatcher = Log::Dispatch->new; my $channel = Log::Dispatch::Perl->new( qw(name default min_level debu +g) ); $dispatcher->add( $channel ); $dispatcher->alert( 'This is an alert' ); __END__ This is an alert Log::Dispatch::Output::log('undef','level','alert','name','def +ault','message','This is an alert') called at /usr/local/lib/perl5/si +te_perl/5.8.3/Log/Dispatch.pm line 95 Log::Dispatch::_log_to('Log::Dispatch=HASH(0xfc578)','level',' +alert','name','default','message','This is an alert') called at /usr/ +local/lib/perl5/site_perl/5.8.3/Log/Dispatch.pm line 74 Log::Dispatch::log('Log::Dispatch=HASH(0xfc578)','level','aler +t','message','This is an alert') called at /usr/local/lib/perl5/site_ +perl/5.8.3/Log/Dispatch.pm line 22 Log::Dispatch::__ANON__('Log::Dispatch=HASH(0xfc578)','This is + an alert') called at line 7

What am I missing?

Liz

Update:
Thanks ysth for the feedback. In the end, it has come to removing the first 4 lines from Carp::longmess. The actual regexp to remove the first 4 lines will become s#^(?:[^\n]*\n){4}##s. New version of Log::Dispatch::Perl is on its way to CPAN.

Replies are listed 'Best First'.
Re: How to lose Carp levels with @CARP_NOT?
by ysth (Canon) on Jan 28, 2004 at 21:47 UTC
    That quote is from the doc explaining how croak, carp, and shortmess work, and doesn't apply to confess, cluck, and longmess.

    I think the distinction is that the former are considered useful for user messages (including programmer using a module) and the latter are not.

      Argh, you're right. Well, that explains why it didn't work.

      Any suggestions, other than calling longmess and removing the appropriate lines manually?

      Liz

        A quick check shows that longmess protects against newlines in the parameters, so manually filtering should work fairly easily (completely untested):
        $longmess =~ s/\n\tLog::Dispatch::(Perl::|::Output::)?[^:]+\(.*//g;
Re: How to lose Carp levels with @CARP_NOT?
by tilly (Archbishop) on Jan 29, 2004 at 16:23 UTC
    There are multiple solutions.

    First of all, I should point out that normally you don't want to do this. If you want a short message, then croak. If you want to provide full debugging information, there is little reason not to provide a little extra. And there is usually good reason not to, because when an error is thrown it can be useful for the developer to have the option of seeing the actual code that decides to throw the message. (Just to trace what has to be fixed.)

    Now one solution is the old internal style. If you want to exclude 4 levels of call exactly, you can play games with $Carp::CarpLevel. Unfortunately whenever one person plays games with that, they break it for everyone else. Also its usage with shortmess messages is obscure at best. Furthermore that gets you into the game of counting how many levels of your module you use.

    The more robust solution is the new internal style. Just stick the line: $Carp::Internal{$_}++ for 'Log::Dispatch::Output', 'Log::Dispatch'; in your module. And now those two packages will be ignored whenever Carp crawls back, looking for where to start reporting the error from.

      The more robust solution is the new internal style. Just stick the line: $Carp::Internal{$_}++ for 'Log::Dispatch::Output', 'Log::Dispatch'; in your module. And now those two packages will be ignored whenever Carp crawls back, looking for where to start reporting the error from.

      How will you know whether a Carp.pm supports this? Check if the %Carp::Internal hash exists already? Or is there some version number check that I can use?

      Liz

        %Carp::Internal was introduced in Perl 5.8. $Carp::CarpLevel was available before that, but was always a bad idea. If you want, you can read a rant or two on why I dislike it.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-03-19 02:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found