Я столкнулся с ситуацией, когда я не могу сдерживать предупреждения интуитивно, потому что perl вставляет вызов встроенной функции. например.
use strict;
use warnings;
{
no warnings 'substr'; # no effect
foo(substr('123', 4, 6)); # out of range but shouldn't emit a warning
}
sub foo {
my $s = shift; # warning reported here
# do something
}
Запуск этого кода приводит к
substr outside of string at c:\temp\foo.pl line 10.
Чтобы заблокировать предупреждение, мне нужно переместить no warnings 'substr'
внутри функции.
sub foo {
no warnings 'substr'; # works here, but there no call to substr
my $s = shift; # no warnings here
# do something
}
Я вижу, что вызов substr
встраивается путем передачи кода через perl -MO=Terse
LISTOP (0x27dcaa8) leave [1]
OP (0x27a402c) enter
COP (0x27dcac8) nextstate
BINOP (0x27dcb00) leaveloop
LOOP (0x27dcb20) enterloop
LISTOP (0x27dcb68) lineseq
COP (0x27dcb88) nextstate
UNOP (0x27dcbc0) entersub [5] # entry point for foo
UNOP (0x27dcbf4) null [148]
OP (0x27dcbdc) pushmark
LISTOP (0x27dcc48) substr [4] # substr gets called here
OP (0x27dcc30) null [3]
SVOP (0x27dcc84) const [6] PV (0x2319944) "123"
SVOP (0x27dcc68) const [7] IV (0x2319904) 4
SVOP (0x27dcc14) const [8] IV (0x231944c) 6
UNOP (0x27dcca0) null [17]
PADOP (0x27dccf4) gv GV (0x2318e5c) *foo
Является ли это поведение оптимизатора документированным где угодно? perlsub
только упоминает вложение постоянных функций. Учитывая, что предупреждение сообщается в неправильной строке и что no warnings
не работает в лексической области, где выполняется вызов, я склонен сообщать об этом как об ошибке, хотя я не могу придумать, как это сделать может быть разумно исправлена при сохранении оптимизации.
Примечание. Это поведение наблюдалось в Perl 5.16.1.