Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Re (tilly) 2: Confusion about properly using Carp

by steves (Curate)
on Mar 03, 2002 at 02:16 UTC ( [id://148925]=note: print w/replies, xml ) Need Help??


in reply to Re (tilly) 2: Confusion about properly using Carp
in thread Confusion about properly using Carp

I disagree. If you know where you are in a calling stack, this has worked for me numerous times:

{ local $Carp::CarpLevel = 2; carp "Some error"; }

No need to worry about croak or confess here that I can see. What am I missing?

Replies are listed 'Best First'.
Re (tilly) 4: Confusion about properly using Carp
by tilly (Archbishop) on Mar 03, 2002 at 03:30 UTC
    What is wrong with this?

    What if someone calling your code wants to do what you are doing? They can't because no matter what they do with $Carp::CarpLevel, you are overriding them.

    What if someone wants to later modify your code? They don't realize that somewhere in the guts you have hardcoded an assumption about the shape of the call-stack. So your code is fragile.

    What if you are wrapping a module which might croak? If so then your callstack calculation is almost surely wrong. Read the guts of Carp to find out why.

    What if you are wrapping a module which might croak and might confess? If so then there is no single way to get the right desired result.

    And on and on. I gave this topic a lot of thought, and I concluded that what you are trying to do is a bad idea. The fact that many people (like you) think they know what they are doing and get it wrong consistently just convinces me of that even more.

      These are good points, but I also gave this thought before doing it. That included examining the Carp code and even adding my own trace code to it to fully understand it. It might surprise you to find that you and I reached similar conclusions. I figured I had three choices:

      • Rewrite Carp. Not too far from your "Wait until 5.8 ..." note
      • Write my own. I also thought this was a bad idea.
      • Set up inheritence paths that matched my desired error reporting. If ever there was a bad reason to use inheritence that would be it.
      So basically I found myself in a state where there was no good solution. And pressed for time. So I did what I had to do.

      To answer your specific points:

      What if someone calling your code wants to do what you are doing? They can't because no matter what they do with $Carp::CarpLevel, you are overriding them.

      The few interfaces where I use this are set up to set caller information on entry to the interface and communicate that down the calling stack. So my example was contrived -- there are no hardcoded $Carp::CarpLevel numbers. Each interface has a mechanism for overriding what's found as the default on entry.

      What if someone wants to later modify your code? They don't realize that somewhere in the guts you have hardcoded an assumption about the shape of the call-stack. So your code is fragile.

      Maybe. But it's documented and there are big comments in the few places where this is done.

      What if you are wrapping a module which might croak? If so then your callstack calculation is almost surely wrong. Read the guts of Carp to find out why.

      I read the guts, so I never use it in situations like this. And I'm still not getting how this is a problem when I only use it in local blocks as shown earlier. Even if code below me is croak'ing, I'm never setting $Carp::CarpLevel until I know it's time for me to complain. I set it, complain and it's unset. So how can that affect an interface below me that's calling croak? Keep in mind that there are zero cases in my code where $Carp::CarpLevel is ever set globally. Each setting is local, in a block with only a call to carp. The code outside of these blocks carries around the call stack information but doesn't use it outside of those local blocks. It seems as if you're thinking I set $Carp::CarpLevel somewhere and leave it that way. That would be truly evil. It's only ever set like this:

      What if you are wrapping a module which might croak and might confess? If so then there is no single way to get the right desired result.

      Same answer as above.

      My question is this: What is the right way to solve this now? I agree that my method has its flaws but I didn't see anything better in 5.6.1. I've been kicking around some better ideas for handling this sort of thing longer term but I needed something that worked quickly.

        Most of your points are accurate.

        But (you knew that was coming) the exact question which started this dicussion was you recommending the use of $Carp::CarpLevel for wrapping a module. Which is exactly what you said that you don't do.

        Despite your assertion that you don't hardcode $Carp::CarpLevel, your example did. If you want to let your caller be more flexible in what they are going to do, you need to:

        { local $Carp::CarpLevel = $Carp::CarpLevel + 2; carp("That isn't nice!"); }
        If you do that, then someone calling your code can decide to edit themselves out of the calling stack. Else they can't.

        Further than that, I note that while it may be possible to figure out the call-level that an error will be called from, that imposes extremely strong requirements on the structure of the code. And even where you had that structure once, it generally doesn't last. (It didn't for Exporter.)

        As for longer term solutions, please download the current development series and take a look at what is offered in its Carp. If that doesn't offer the control that you want, now is the time to raise your voice...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://148925]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-03-28 15:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found