Без особых причин я играл с прототипом glob (*)
и видел, что он будет делать, когда аргумент является определенной подпрограммой.
С учетом следующего кода:
sub test (*) {print "[@_]\n"}
sub blah ($) {"blah got @_"}
Если вы пишете test blah;
, вы получите синтаксическую ошибку Not enough arguments for main::blah...
Если вы пишете test blah 1;
, программа компилирует и печатает [blah]
Если вы пишете test blah die;
, программа компилирует, печатает [blah]
и не умирает.
Если вы пишете test blah(1);
, программа компилирует и печатает [blah got 1]
Если вы пишете test blah(die);
, программа компилируется и затем умирает.
Два последних примера явно являются приложением "если он выглядит как вызов подпрограммы, это правило вызова подпрограммы".
Однако примеры без округлых скобок мне кажутся ошибкой. Поскольку, по-видимому, происходит то, что, несмотря на то, что он находится в глобальном контексте, парсер по-прежнему рассматривает blah
как прототипированную функцию, которая требует аргумента. Но когда компиляция произносится и выполняется, аргумент blah
полностью отбрасывается, а строка 'blah'
вместо этого передается в test
.
Ниже приведен пример конструкции test blah die;
, проходящей через B::Deparse
:
$ perl -MO=Deparse,-p -e 'sub test (*) {print "[@_]\n"} sub blah ($) {"blah got @_"} test blah die;'
sub test (*) {
print("[@_]\n");
}
sub blah ($) {
"blah got @_";
}
&test('blah');
-e syntax OK
Итак, как вы можете видеть, die
полностью удаляется из op-дерева.
Итак, мой вопрос: если другие считают это поведение ошибкой? Является ли поведение документированным где угодно? Если это ошибка, стоит ли ее исправлять?