Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

"warn" is your best friend

by snax (Hermit)
on Mar 23, 2014 at 04:14 UTC ( #1079426=perlmeditation: print w/replies, xml ) Need Help??

It's been nearly ten years since I've said anything here. Somehow, this seems appropriate. I, as many perl hackers have, tend default to quick "print" statements for debugging, only to be shot down when throwing my code at, say, multiple input files at once, for example. No longer. Sure, your code works for *most* of the files, but something is twitchy somewhere. Unicode when you expected ASCII. A mix of LF/CRLF line endings. CR line endings (horrors!) even :) But: if you print where you think things are going wrong, that output goes in the STDOUT queue. The errors that pop when things go wrong happen in the STDERR queue. Hence, "warn" is your bestest friend evars! Trust me on this. You'll get all sorts of win using "warn" context points when you want to debug via print-ing.

Replies are listed 'Best First'.
Re: "warn" is your best friend
by kcott (Archbishop) on Mar 23, 2014 at 05:37 UTC

    G'day snax,

    Welcome back after your decade-long sabbatical.

    Yes, I agree warn can be quite handy in this sort of situation. It also allows you to quickly search your code for development debugging statements and, for production code, remove them, comment them out, or even convert them for whatever standard debugging/logging system is being used.

    While I'm sure you're aware of it, I thought I'd just point out carp() and cluck() (from the built-in Carp module). These also output to STDERR and, depending on your requirements, may produce more useful information.

    -- Ken

Re: "warn" is your best friend
by moritz (Cardinal) on Mar 23, 2014 at 08:02 UTC

    Since you mentioned Unicode: Many Perl programs these days set up STDOUT correctly to encode the output, but forget to the same with STDERR (and yes, I myself am guilty of this many times over).

    So when debug-outputting non-ASCII strings to STDERR, you need to be extra aware of encoding issues.

    (That said, when debugging encoding issues, I usually set $Data::Dumper::Useqq = 1 and debug with Data::Dumper, so it's not that much of an issue; but if you want to warn plain strings, you must be aware of it).

Re: "warn" is your best friend
by Bloodnok (Vicar) on Mar 23, 2014 at 12:08 UTC
    As the other contributors have already said, warn can be your best friend with some caveats, when print STDERR ... becomes a better friend - especially in my case, where I have a habit of attempting to use warn whilst trying to debug a failing test case ... entirely forgetting that the test cases use (pun intended:-) Test::Warnings which 'eat up' all warnings and pass/fail accordingly, thus providing, IMO, a more than reasonable demonstration of Heisenbergs' Uncertainty Principle :-D

    A user level that continues to overstate my experience :-))

      You want to know my trick for that? When debugging, instead of outputting with warn $message, output messages with ::diag $message.


      • ::diag outputs messages prefixed with a "#" sign, so it looks nice in test output.

      • ::diag won't cause Test::Warnings fails.

      • When you're not running your test suite, Test::More probably won't be loaded, so the ::diag function won't exist. This will cause ::diag $message to bomb loudly, so you won't forget any debugging messages you've scattered amongst your code.

        Note that because of the way function calls are parsed in Perl, including parentheses in the function call like ::diag($message) will make it bomb at run-time instead of compile-time. This is why I recommend not using the parentheses in ::diag $message. If you need to resolve ambiguities using parentheses, you can always do so with external ones like (::diag $message).

      • Along the same lines, a statement that starts with :: looks weird, so will stand out like a sore thumb when you're looking for it to remove it.

      use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
        Hiya tobyink,

        Much as tho' I like and indeed really appreciate, your insight into debugging the test cases, I was actually referring to the use of spurious debugging statement(s) in the code itself - where my use of warn suggested that the code was even more broken than and in a different place to, the actual problem.

        A user level that continues to overstate my experience :-))
Re: "warn" is your best friend
by GrandFather (Saint) on Mar 25, 2014 at 00:55 UTC

    Actually I find a good IDE, breakpoints and variable contents viewing a lot more powerful and much faster than any sort of print/warn/::diag/Carp/... based technique. Even the Perl command line debugger is vastly quicker for resolving issues than any print based technique (I used Perl's command line debugger for the first time in 3 years yesterday and was sufficiently up to speed with it in 10 minutes).

    I use Carp for reporting bad states (unexpected parameters for example) and die for exception handling internally. Those often point to areas where a little debugging is required, but then it's set a breakpoint and inspect the state directly - even changing variable contents on the fly to explore issues further. For me with, any half decent development environment available, print based debugging stopped 30 years ago.

    If the code changes take longer than the time saved, it's fast enough already.
      Actually, it's best to just log everything. And yes, you are right, there had been vim and emacs available 30 years ago.


      ugh, reading talks like this make me wonder why anyone uses java...

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1079426]
Approved by kcott
Front-paged by skx
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2023-11-29 05:51 GMT
Find Nodes?
    Voting Booth?

    No recent polls found