Без особых причин я играл с прототипом 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-дерева.
Итак, мой вопрос: если другие считают это поведение ошибкой? Является ли поведение документированным где угодно? Если это ошибка, стоит ли ее исправлять?