How can you get Perl to stop when referencing an undef value?
Asked Answered
W

6

15

How do you get Perl to stop and give a stack trace when you reference an undef value, rather than merely warning? It seems that use strict; isn't sufficient for this purpose.

Waynant answered 16/9, 2008 at 22:30 Comment(0)
W
20
use warnings FATAL => 'uninitialized';

use Carp ();
$SIG{__DIE__} = \&Carp::confess;

The first line makes the warning fatal. The next two cause a stack trace when your program dies.

See also man 3pm warnings for more details.

Williswillison answered 16/9, 2008 at 22:32 Comment(1)
As an alternative to the last two lines, use Carp::Always.Paton
N
15

Instead of the messy fiddling with %SIG proposed by everyone else, just use Carp::Always and be done.

Note that you can inject modules into a script without source modifications simply by running it with perl -MCarp::Always; furthermore, you can set the PERL5OPT environment variable to -MCarp::Always to have it loaded without even changing the invocation of the script. (See perldoc perlrun.)

Noam answered 16/9, 2008 at 23:11 Comment(0)
W
4

Include this:

use Carp ();

Then include one of these lines at the top of your source file:

local $SIG{__WARN__} = \&Carp::confess;
local $SIG{__WARN__} = \&Carp::cluck;

The confess line will give a stack trace, and the cluck line is much more terse.

Waynant answered 16/9, 2008 at 22:32 Comment(0)
F
2

One way to make those warnings fatal is to install a signal handler for the WARN virtual-signal:

$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };
Fronde answered 16/9, 2008 at 22:33 Comment(0)
G
1

Referencing an undef value wouldn't be a problem in itself, but it may cause warnings if your code is expecting it to be something other than undef. (particularly if you're trying to use that variable as an object reference). You could put something in your code such as:

use Carp qw();

[....]

Carp::confess '$variableName is undef' unless defined $variableName;

[....]
Garretgarreth answered 16/9, 2008 at 22:32 Comment(0)
R
0

You have to do this manually. The above "answers" do not work! Just test out this:

use strict;
use warnings FATAL => 'uninitialized';
use Carp ();
$SIG{__DIE__} = \&Carp::confess;

my $x = undef; # it would be enough to say my $x;
if (!$x->{test}) {
print "no warnings, no errors\n";
}

You will see that dereferencing did not cause any error messages or warnings. I know of no way of causing Perl to automatically detecting the use of undef as an invalid reference. I suspect this is so by design, so that autovivification works seamlessly.

Rottenstone answered 3/5, 2011 at 17:10 Comment(2)
an empty hash produces 0. This appears to be a special case.Antithesis
I think if ($var) is specially handled (for convenience) to treat undef as false. Maybe if ("$var") makes the difference.Whirlybird

© 2022 - 2024 — McMap. All rights reserved.