On 5/20/07, Uri Guttman <[EMAIL PROTECTED]> wrote:
> >>>>> "BT" == Ben Tilly <[EMAIL PROTECTED]> writes:
>
>   BT> The purpose of using goto there is in case some code uses caller() and
>   BT> could get confused about the extra subroutine.  (For instance Carp
>   BT> would be likely to warn at the enclosing subroutine that you defined.)
>
> i ran into that problem when doing error handling in file::slurp. i
> wanted an error handler to be called in several places which would carp
> to the correct level (and also return directly to the caller). so magic
> goto was my answer at the time. but i have since learned that carp (or
> some cpan variant) can be used properly several call levels down from
> the original call into a module. i think it backtraces to find a package
> different from the one that did the carping (where you are now). i
> haven't looked at it in detail but it sounds like it would be useful in
> this case too.

Carp has a number of APIs to allow people to control where it carps
from.  The documentation explains them in detail.  The one that
everyone thinks is right but which is almost always a misuse is to use
$Carp::CarpLevel.  If you read the Perl 5.8 documentation you'll find
instructions on how to use them.  Please disregard those instructions,
they are horribly wrong.  (Yes, I've submitted a patch.)

The right way to control where and when you carp is to use @ISA,
@CARP_NOT, %Carp::Internal and %Carp::CarpInternal.  Here is a brief
explanation of how to do that.

First of all Carp will issue its warning on the first "untrusted"
call.  By default, Carp's notion of a trusted call is "one package
inherits from the other".  It doesn't matter whether the caller
inherits from the callee or the other way around, that call is
trusted.  As you might expect, this trust relationship is recursively
generated by inspecting @ISA.  Normally this works pretty well, but
occasionally you want a different rule.  Therefore you can use
@CARP_NOT to override the implicit "direct trust" relationship that is
inferred from @ISA.

Of course there are a few calls that we want to not carp no matter
what.  There are two levels of control there, both of which are meant
to be used by the Perl core.  The first is to add your package to
%Carp::Internal.  That's a list of packages that you'll never get a
carp or confess from.  The main purpose of that is to make sure that
complete stack backtraces start from within user code rather than Perl
code.  The other mechanism is to add your package to
%Carp::CarpInternal, which is like %Carp::Internal except that calls
TO those packages will never trigger a carp.  It is this rule that
keeps a carp from being generated on the line where you call carp.

In hindsight this API is too complex and not flexible enough.  What
should have been done is to provide an additional level of control,
which is that if a package defines the function CARP_NOT then that
function should be called with the details of a call to figure out
whether or not a carp warning should be generated on that call.  Then
people could set up their own modules with whatever carp rules they
wanted.

Ah well.  That wouldn't be a hard change to make if someone wanted to
make it.  My only excuse for the bad API is that at the time nobody
was interested in discussing it with me, and my only significant use
case when I came up with it is that I wanted Exporter to do a better
job of reporting errors on the right line.  (And I certainly succeeded
in that.)

Cheers,
Ben
 
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to