This program
use warnings;
use strict;
use feature qw(say);
{
#use autodie; # all good when this is uncommented
no autodie;
}
open my $OLDSTD, '>&', *STDOUT; #--> line 10 (program fails)
open *STDOUT, '>', 'stdout.out';
say "$$ done";
aborts with
Undefined subroutine called at problem_no_autodie.pl line 10.
To restate the comment in code: if there is a use autodie;
statement first then all is well. (All is well with only use autodie;
as well.) Curiously, in the same scope with no autodie
statement I see no such problems either; only code outside of its scope fails! Kinda anti-scoping, eh?
If this scoped no autodie
comes after the use of *STDOUT
then it's all good again. Further use of *STDOUT
, after (the scoped) no autodie
, fails the program.
There is a Gotcha mentioned in docs that involves barewords (which I don't fully understand), and the program indeed fails with STDOUT
-- but I have it as *STDOUT
.
So it appears that *STDOUT
is treated as a user's sub, but I don't understand that nor how the scope of autodie
gets defeated. (Scope leakage is mentioned as a bug in some versions but in a seemingly unrelated way.) And there is a practical problem with this.
I don't use autodie
in my code. But consider this sub, which I do use
sub isatty {
no autodie;
state $isatty = open(my $tty, '+<', '/dev/tty');
return $isatty;
}
It is legitimate for that open
to fail, so we have to disable autodie
in that scope in case the user of the sub has it on. Then is the described behavior going to hurt? Under what circumstances?
I am puzzled by this effect of no autodie
and by its leakage out of its scope, and by all their strange details. But the real concern is that I am not sure how to protect the code that uses a library like the one above against that behavior, since I don't understand it. Any ideas?
I see this under 5.16.3 (system), 5.26.2 and 5.30.0 (perlbrew) on CentOS 7.8
I do not see this behavior on 5.32.0; no failure there.
The ... or die $!
check with open
didn't make any difference so it's not shown for simplicity.