Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Should I use carp/croak or warn/die

by SBECK (Hermit)
on May 30, 2018 at 14:59 UTC ( #1215465=perlquestion: print w/replies, xml ) Need Help??

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

I recently got a request to use carp/croak instead of warn/die in a module of mine. Since I'm going to be releasing a new version soon, now's a good time to address that request. I've sometimes used Carp, but in general found that I didn't really need the more extensive output, so I've tended to stick to warn/die . However, I'm not opposed to doing so if it is generally considered a best practice.

Unfortunately, a google/perlmonks search didn't turn up an answer. A quick glance at some of the modules distributed in core showed that some use Carp, some don't so that didn't provide a definitive answer either.

So I'll turn to you. Is it generally considered a best practice to use Carp (or conversely, is it a best practice NOT to use Carp in most cases)? Is this written down anywhere (obviously I didn't find it, but if I overlooked something, I'd like to be educated about that).

Replies are listed 'Best First'.
Re: Should I use carp/croak or warn/die
by haukex (Bishop) on May 30, 2018 at 15:08 UTC

    Note that Carp doesn't automatically include a stack trace, that's only if you do perl -MCarp=verbose script.pl or $Carp::Verbose=1;, or you explicitly use confess. I like to use Carp in my modules because it reports the error as coming from the user's code, rather than the module itself, which makes more sense for many error cases (like incorrect parameters). When it's an internal error that I don't expect the user to see (at least not often), I'll sometimes use confess to get the full stack trace.

    $ cat Foo.pm package Foo; use warnings; use strict; use Carp; sub one { die "Bad call to one"; } sub two { carp "Bad call to two"; } sub three { confess "Some error in three"; } 1; $ perl -I. -MFoo -le 'Foo::one' Bad call to one at Foo.pm line 5. $ perl -I. -MFoo -le 'Foo::two' Bad call to two at -e line 1. $ perl -I. -MFoo -le 'Foo::three' Some error in three at Foo.pm line 7. Foo::three() called at -e line 1
      Thank you. I think you've just convinced me to use Carp, at least in some instances.
Re: Should I use carp/croak or warn/die
by hippo (Chancellor) on May 30, 2018 at 15:09 UTC

    Personally speaking I prefer to use carp/croak when it's the fault of the caller and warn/die when it's the fault of the current sub. That way the message is appropriately relevant. I'm unaware of any recommendation of best practice which says always to use one or the other.

        Honestly, I did almost add "but it's probably in PBP somewhere" to my previous post. :-) Thanks for the reference, though.

        Note that even there it's an arbitrary distinction as perlcritic won't moan at newline-terminated warn/die calls.

        $ echo 'package Foo; use strict; use warnings; warn "foo!"; 1;' | perl +critic -3 "warn" used instead of "carp" at line 1, column 40. See page 283 of P +BP. (Severity: 3) $ echo 'package Foo; use strict; use warnings; warn "foo!\n"; 1;' | pe +rlcritic -3 source OK $
        Thanks for the reference. Although I don't agree with all of the recommendations of perl critic, I have learned a lot from reading through it's suggestions. I'll go back and reread this section for sure.
Re: Should I use carp/croak or warn/die
by ikegami (Pope) on May 30, 2018 at 15:50 UTC

    I've sometimes used Carp, but in general found that I didn't really need the more extensive output

    carp and croak don't make the output more extensive; they just report the caller to be the source of the error instead of the line where the error was found.

    $ perl -Mlib=. -MMod -e'Mod::foo();' Insufficient arguments at Mod.pm line 5. # carp Insufficient arguments at -e line 1. # warn

    They also have the advantage of being able to produce a full stacktrace on demand (e.g. PERL5OPT=-MCarp::Always). ...Oops, that also works for warn and die.

    $ PERL5OPT=-MCarp::Always perl -Mlib=. -MMod -e'Mod::foo();' Insufficient arguments at Mod.pm line 5. Mod::foo() called at -e line 1 Insufficient arguments at Mod.pm line 6. Mod::foo() called at Mod.pm line 6. Mod::foo() called at -e line 1
Re: Should I use carp/croak or warn/die
by BrowserUk (Pope) on May 30, 2018 at 15:04 UTC

    I'd ask the question of the requester: Why? What benefit do they expect to derive from it?

    It gives more data; but generally, that data is only information to those that need to dig around in the guts of the called modules. Ie authors.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
Re: Should I use carp/croak or warn/die
by LanX (Cardinal) on May 30, 2018 at 16:13 UTC
    On a meta level ...

    Personally I find the interface not too convincing

    • The words "carp", "cluck" and "croak" are far from basic English and hard to explain to colleagues. ( Why do ravens "die" while a fish only "warns"?)
    • The connotation to the caller is not evident for me. (Do ravens croak to (telephone) callers?)
    • Sometimes I'd like to also have a stack-trace for warn/die (i.e. from the actual error line - yes I know Devel::Confess but why an extra module?)
    • Sometimes I don't know how many levels up the user of my module called. Having an option to "carp" from the first caller in a different package would be nice. (This is more a nice to have) happens already.
    I ended up writing my own routines handling all of this, because we have to install our own die-handlers too, but I'm far from having a convincing solution yet.

    Even considering the interface ...

    ... maybe something like warn_up $level, msg with special "levels", like a package-regex or something and negative numbers for stack-trace.

    Nevertheless thanks for the question, frontpaged! =)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      I'm guessing it's an Americanism. Sorry about that to the rest of the world ;)

      "Carping" is slang for complaining about something. ex: He was carping about the wait for a table. "Croaking" is slang for dying. ex: Your pet fish croaked last night

      They were rare in my youth, and outside of Perl, I haven't heard them used in probably 30 years.

      Update: Just for kicks, here are some synonyms for "carp" from the Merriam-Webster dictionary: bellyache, bleat, caterwaul, croak, fuss, gripe, grouse, nag, whine, and whinge. It could have been worse.

        Actually, "carp", used as a verb, meaning complain, has been in use since the 1500s, so is long past the slang stage.

        However, "croak" is still considered a slang term.

        Well yes, I can construct mnemonics, German and English being very similar helps.

        But still I'm confused about the need to have several names for things which are almost similar - i.e. different only in orthogonal dimensions - instead of parametrizing them.

        Thanks anyway! =)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      Thanks for your reply! When/if you ever release the a module to do this, I definitely would want to use it. I'm learning that I really need to rethink how I do warn/die (or their equivalent).
      Having an option to "carp" from the first caller in a different package would be nice.
      This is how carp and croak always work.
        Yeah I noticed in the meantime

        See Re^4: Should I use carp/croak or warn/die (@CARP_NOT)

        Though I'm not happy about the documentation.

        the Synopsis says

        > warn user (from perspective of _caller_)

        But later the doc says inside the text

        > carp() or croak() which report the error as being from where your module was called.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      > Sometimes I don't know how many levels up the user of my module called. Having an option to "carp" from the first caller in a different package would be nice. (This is more a nice to have)

      Though I'm not sure if @CARP_NOT could be used for this ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        From my experience, mucking with the likes of caller and/or any aspect of such an undertaking of tracking and reporting from nested modules and subs is fraught with frustration, angst, head-desking and oftentimes throwing things... particularly when dealing with anony-subs and the like :)

        Though I'm not sure if @CARP_NOT could be used for this ...
        How could it?

        I mean @CARP_NOT is a package variable that is (or so I suppose) evaluated at compile-time.

        How could that be used to implement the run-time feature of reporting the the first caller of a different package?

        I don't really know to be honest, you could be right, but my working hypothesis here is that you're simply blah-blahing here.

        So please enlighten us...

Re: Should I use carp/croak or warn/die
by Anonymous Monk on May 31, 2018 at 13:11 UTC
    I think we're beginning to carp about this ...

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2020-10-21 13:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (217 votes). Check out past polls.

    Notices?