Perl warnings and the warn function
Tags: perl, warnings, logging
Published: 2022-01-04 19:42:52

---
title: Perl warnings and the warn function
published: true
date: 2022-01-04 15:00:00 UTC
tags: Perl,warnings,logging
canonical_url: https://phoenixtrap.com/2022/01/04/perl-warnings-and-the-warn-function/
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1nhralv5z9i379xg6ef.jpg
---

I mentioned in passing [last week](https://phoenixtrap.com/2021/12/28/avoid-yoda-conditions-in-perl-you-should/) that the next major release of Perl, v5.36, is set to enable [`warnings`](https://perldoc.perl.org/warnings) by default [for code that opts in to `use v5.35;` or above](https://metacpan.org/release/NEILB/perl-5.35.7/view/pod/perl5353delta.pod#Core-Enhancements). Commemorating Perl’s 34th birthday [the week before that](https://phoenixtrap.com/2021/12/21/34-at-34-for-v5-34-modern-perl-features-for-perls-birthday/), I noted that the [warnings system has been getting ever finer-grained](https://phoenixtrap.com/2021/12/21/34-at-34-for-v5-34-modern-perl-features-for-perls-birthday/) since its introduction in 2000. And fellow Perl blogger and [CPAN author Tom Wyant](https://metacpan.org/author/WYANT) has been cataloging his favorites over the past several months—the latest as of this writing was [on the “ambiguous” category of warnings](http://blogs.perl.org/users/tom_wyant/2021/12/my-favorite-warnings-ambiguous.html), and you can find links to previous entries in his series at the bottom of that post.

It occurred to me afterward that there may be some confusion between the `warnings` pragma and the related [`warn` function](https://perldoc.perl.org/functions/warn) for reporting arbitrary runtime errors. `warn` outputs its arguments to the [standard error (`STDERR`) stream](https://perldoc.perl.org/perlglossary#standard-error), or if it’s not given any then you get a string with any exception from `$@` (`$EVAL_ERROR` under `use English`) followed by a tab and then “`...caught at <file> line x.`” If that’s empty too, a plain `warn` just says, “`Warning: something's wrong at <file> line x.`”, which isn’t exactly helpful, but then again you didn’t give it much to go on.

`warn` output doesn’t have to go to `STDERR`, and this is where the relation to the warnings pragma comes in because both are governed by the ` __WARN__ ` signal handler in the [`%SIG` hash](https://perldoc.perl.org/variables/%25SIG). Normally, you might opt to only display runtime warnings if a debugging flag is set, like so:

```perl
#!/usr/bin/env perl

use strict;
use warnings;

my $DEBUG = 0;
$SIG{ __WARN__ } = sub { warn @_ if $DEBUG };
warn 'shhh'; # silenced

$DEBUG = 1;
warn 'hello warnings';
```

But if you set that signal handler in a `BEGIN` block, it catches compile-time warnings too, in which case flipping a flag after the fact has no effect—the compiler’s already run:

```perl
#!/usr/bin/env perl

use strict;
use warnings;

my $DEBUG = 0;
BEGIN { $SIG{ __WARN__ } = sub { warn @_ if $DEBUG } }
my $foo = 'hello';
my $foo = 'world'; # no warning issued here

$DEBUG = 1;
my $foo = 'howdy'; # still nothing
```

By the way, both ` __WARN__ ` and ` __DIE__ ` hooks are also used by the [Carp module](https://perldoc.perl.org/Carp) and its friends, so you can use the same technique with their enhanced output:

```perl
#!/usr/bin/env perl

use strict;
use warnings;
use Carp qw(carp cluck);

my $DEBUG = 0;
BEGIN { $SIG{ __WARN__ } = sub { warn @_ if $DEBUG } }
carp 'quiet fish';

$DEBUG = 1;
loud_chicken();

sub loud_chicken {
    cluck 'here comes a stack trace';
}
```

You _could_ use these as stepping stones towards a debug log for larger applications, but at that point, I’d suggest looking into one of the logging modules on CPAN like [Log::Log4perl](https://metacpan.org/pod/Log::Log4perl) (not to be confused with that [lately-problematic Java library](https://phoenixtrap.com/2021/12/14/a-brief-note-on-log4perl/)), [Log::Dispatch](https://metacpan.org/pod/Log::Dispatch) (which can be [wired into Log4perl](https://metacpan.org/pod/Log::Log4perl#Additional-Appenders-via-Log::Dispatch)), or [something else](https://metacpan.org/pod/Task::Kensho::Logging) to suit your needs.

---

_Cover image: ["Warning!"](https://www.flickr.com/photos/38834306@N00/2049428733) by [John Goodridge](https://www.flickr.com/photos/38834306@N00) is licensed under [CC BY-NC-SA 2.0](https://creativecommons.org/licenses/by-nc-sa/2.0/?ref=openverse&atype=html)_