Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Perl: porters
Why aren't %Carp::Internal and %Carp::CarpInternal documented?
 

Index | Next | Previous | View Flat


btilly at gmail

Oct 21, 2006, 11:19 PM


Views: 468
Permalink
Why aren't %Carp::Internal and %Carp::CarpInternal documented?

Glancing at the source code for a current copy of Carp, I see that Jos
I. Boumans <kane[at]dwim.org> claimed that %Carp::CarpInternal and
%Carp::Internal do not work as advertised and therefore removed the
documentation. That is false. I just double-checked, and they do
what I said they did. Really.

What putting a package in %Carp::Internal does is keeps Carp from
deciding that an error should be reported as being from a call from
that package to somewhere else. What putting a package in
%Carp::CarpInternal does is keeps Carp from deciding that an error
should be reported as being from a call to that package.

If anyone wants to test it, all of the major cases are tested in the
program at the end of this email. In this program there are 4 calls
of interest. We have main line 1 calls, calls Foo line 1, calls Bar
line 1, calls Baz line 1 which carps. I try all 16 combinations of
having Bar and Baz in or not in %Carp::Internal and
%Carp::CarpInternal. If you run it, you will find the following:

- The message is reported at Bar line 1 unless the call from Bar to
Baz is marked safe by having Baz in %Carp::CarpInternal or Bar in
%Carp::Internal.

- If Baz is in %Carp::CarpInternal or Bar is in %Carp::Internal, the
message is reported at Foo line 1 or main line 1 depending on whether
the call from Foo to Bar is marked safe by Bar being in
%Carp::CarpInternal.

In short if A calls B, that call can be marked safe by having A be in
%Carp::Internal or by having B be in %Carp::CarpInternal. Exactly as
was once advertised.

Furthermore looking at the documentation for Carp, I see that there is
now documentation of global variables. %Carp::Internal and
%Carp::CarpInternal are not documented. But $Carp::CarpLevel is.
However $Carp::CarpLevel is far more problematic than the other two.

As an illustration I point you to
http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2006-10/msg00324.html
where David Nicol demonstrates how one should NOT implement a certain
piece of functionality. His implementation will cause any croak or
carp to either report errors as being from a package very high in the
call stack that has nothing to do with the error, or will turn
carp/croak into cluck/confess. The reason being that the accounting
of calls that he's doing assumes that he has to bump $Carp::CarpLevel
up one for every call level. Which is right for cluck/confess, but is
very, very wrong for carp/croak. (You actually want to bump it one
for each package that it wouldn't decide to skip on its own. Deciding
whether it would skip a package requires doing what Carp does in
Carp::Heavy's short_error_loc.)

Incidentally the right way to do what David Nicol was trying to do in
his code is:

$Carp::Internal{ __PACKAGE__ } = 1;

And then just use the regular functions from Carp.

Regards,
Ben

PS Here is the test program

#! /usr/bin/perl -w
use strict;

*STDERR = *STDOUT;
for my $bar_internal (0, 1) {
$Carp::Internal{Bar} = $bar_internal;
for my $bar_carpinternal (0, 1) {
$Carp::CarpInternal{Bar} = $bar_carpinternal;
for my $baz_internal (0, 1) {
$Carp::Internal{Baz} = $baz_internal;
for my $baz_carpinternal (0, 1) {
$Carp::CarpInternal{Baz} = $baz_carpinternal;
print "Bar "
. ($bar_internal ? "is" : "isn't")
. " in %Internal\n";
print "Bar "
. ($bar_carpinternal ? "is" : "isn't")
. " in %CarpInternal\n";
print "Baz "
. ($baz_internal ? "is" : "isn't")
. " in %Internal\n";
print "Baz "
. ($baz_carpinternal ? "is" : "isn't")
. " in %CarpInternal\n";
# line 1 "main"
Foo::foo();
print STDERR "\n";
}
}
}
}

package Foo;
sub foo {
# line 1 "Foo"
Bar::bar();
}

package Bar;
sub bar {
# line 1 "Bar"
Baz::baz();
}

package Baz;
use Carp qw(cluck);
sub baz {
# line 1 "Baz"
cluck("Baz::baz was called");
}

Subject User Time
Why aren't %Carp::Internal and %Carp::CarpInternal documented? btilly at gmail Oct 21, 2006, 11:19 PM
    Re: Why aren't %Carp::Internal and %Carp::CarpInternal documented? btilly at gmail Oct 22, 2006, 2:07 PM
    Re: Why aren't %Carp::Internal and %Carp::CarpInternal documented? davidnicol at gmail Oct 22, 2006, 9:17 PM
    Re: Why aren't %Carp::Internal and %Carp::CarpInternal documented? twists at gmail Oct 23, 2006, 9:17 AM
    Re: Why aren't %Carp::Internal and %Carp::CarpInternal documented? btilly at gmail Oct 23, 2006, 10:30 AM
    Re: Why aren't %Carp::Internal and %Carp::CarpInternal documented? btilly at gmail Oct 23, 2006, 10:42 AM
    Re: Why aren't %Carp::Internal and %Carp::CarpInternal documented? rgarciasuarez at gmail Nov 14, 2006, 2:19 AM

  Index | Next | Previous | View Flat
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.