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

