После scoped `no autodie` программа не работает на` *STDOUT`
Эта программа
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";
прерывается с
Неопределенная подпрограмма вызывается в строке 10 problem_no_autodie.pl.
Чтобы переформулировать комментарий в коде: если есть
use autodie;
заявление сначала тогда все хорошо. (Все хорошо только с
use autodie;
тоже.) Любопытно, что в одном объеме с
no autodie
заявление Я тоже не вижу таких проблем; только код за пределами его области действия не работает! Что-то вроде анти-прицела, а?
Если это ограничено
no autodie
приходит после использования
*STDOUT
тогда все снова хорошо. Дальнейшее использование
*STDOUT
, после (в области видимости)
no autodie
, программа не работает.
Существует Гоча упоминается в документации, которая вовлекает barewords (который я не полностью понимаю), и программа действительно терпит неудачу с
STDOUT
- но у меня это как
*STDOUT
.
Получается, что
*STDOUT
рассматривается как подписка пользователя, но я не понимаю ни этого, ни того, как
autodie
терпит поражение. (Утечка области видимости упоминается как ошибка в некоторых версиях, но, по-видимому, не имеющим отношения к делу.) И здесь есть практическая проблема.
Я не использую
autodie
в моем коде. Но рассмотрим этот саб, который я использую
sub isatty {
no autodie;
state $isatty = open(my $tty, '+<', '/dev/tty');
return $isatty;
}
Это законно
open
потерпеть неудачу, поэтому мы должны отключить
autodie
в этой области, если он есть у пользователя сабвуфера. Тогда при каких обстоятельствах описанное поведение может навредить?
Меня озадачивает такой эффект
no autodie
и по его утечке за рамки, и по всем их странным деталям. Но реальная проблема заключается в том, что я не уверен, как защитить код, использующий библиотеку, подобную той, что приведена выше, от такого поведения, поскольку я этого не понимаю. Есть идеи?
Я вижу это в разделах 5.16.3 (система), 5.26.2 и 5.30.0 (perlbrew) на CentOS 7.8
Я не вижу такого поведения в версии 5.32.0; нет сбоев.
В
... or die $!
проверьте, что идет с
open
не имеет никакого значения, поэтому для простоты это не показано.
1 ответ
Эта ошибка появилась в autodie 2.24 и исправлена в autodie 2.30.
$ ( cd ./autodie-2.23; perl Makefile.PL >&3; make >&3; perl -Mblib ../a.pl && echo ok ) 3>/dev/null
ok
$ ( cd ./autodie-2.24; perl Makefile.PL >&3; make >&3; perl -Mblib ../a.pl && echo ok ) 3>/dev/null
Undefined subroutine called at ../a.pl line 10.
$ ( cd ./autodie-2.29; perl Makefile.PL >&3; make >&3; perl -Mblib ../a.pl && echo ok ) 3>/dev/null
Undefined subroutine called at ../a.pl line 10.
$ ( cd ./autodie-2.30; perl Makefile.PL >&3; make >&3; perl -Mblib ../a.pl && echo ok ) 3>/dev/null
ok
$ ( cd ./autodie-2.31; perl Makefile.PL >&3; make >&3; perl -Mblib ../a.pl && echo ok ) 3>/dev/null
ok
(2.30 отсутствует на CPAN.)
Чтобы защититься от этой проблемы, добавьте зависимость от autodie 2.30 или выше.