Чтобы <>
работал с STDIN
, он должен вызываться, когда @ARGV
пусто. Если в @ARGV
есть имена файлов при запуске <>
, они удаляются оттуда по мере чтения файлов, а затем вам нужно снова вызвать <>
, чтобы дождаться STDIN
.
perl -wE'if (@ARGV) { print while <> }; print while <>' file
Второй print while <>
ожидает STDIN
(без него печатается file
и программа завершается).
В принципе, это может произойти с вашим сабвуфером, если бы он прочитал все файлы с @ARGV
и как только элемент управления вернулся к вызову <>
в главном, который затем ожидал бы STDIN
.
Однако ваш подчиненный локализует @ARGV
(хорошая практика!), Поэтому после выхода из глобального @ARGV
все равно имеет то, что делал в начале. & dagger; Затем while
в основном считывает эти файлы (снова), получает тот undef
, который он должен получить в конце последнего файла, и завершается.
Один из способов увидеть это: удалить все из @ARGV
после вызова подпрограммы, считывающей input, и перед while
в main. Затем этот while
будет ждать STDIN
снова, независимо от подпрограммы. Как
perl -wE'
sub ri { local @ARGV = @_; return <> };
print for ri(@ARGV);
say"argv: @ARGV";
@ARGV=();
print while <>
' file
(Обратите внимание на то, что ваш пример использует два файла, в то время как подпрограмма имеет дело с одним, так что даже если подпрограмма должна была использовать глобальный @ARGV
(не local
-ized) и удалить файл из @ARGV
, там все равно остался бы один файл, чтобы занимать while
в главном. Так что вы все равно не получите STDIN
.)
Еще один способ увидеть все это: добавить еще один print while <>
, в конце; что один будет ждать STDIN
.
Все это описано в Операторы ввода / вывода (perlop) , хотя это требует довольно близкого прочтения.
& dagger; & thinsp; При local $GLOBAL_VAR;
значение $GLOBAL_VAR
копируется и восстанавливается при выходе из этой области. Таким образом, local защищает глобальную переменную от изменений в пределах своей области.