Согласно perldoc open
:
[...] вы можете открывать файловые дескрипторы непосредственно в скалярах Perl с помощью:
blockquote> [ 1127], см. Также PerlIO :: scalar . Далее, в соответствии с perldoc perlop :open(my $fh, ">", \$variable) || ..
Нулевой дескриптор файла <> является специальным: его можно использовать для эмуляции поведения
blockquote>sed
иawk
, а также любого другая программа фильтра Unix, которая берет список имен файлов, делая то же самое для каждой строки ввода из всех них. Ввод из<>
поступает либо из стандартного ввода, либо из каждого файла, указанного в командной строке. Вот как это работает: при первом вычислении<>
проверяется массив@ARGV
, и если он пуст, для$ARGV[0]
устанавливается значение"-"
, которое при открытии дает стандартный ввод. Затем массив@ARGV
обрабатывается как список имен файлов.Поэтому, когда вы сделаете
while (<>)
, он попытается «открыть стандартный ввод» (при условии, что вы не указали аргументы командной строки, т. Е.@ARGV
пусто). Эта командаopen
не зависит от текущего значения переменнойSTDIN
, вместо этого (я полагаю) она просто сделает что-то вроде:open ARGV, '/dev/tty' or die "open: /dev/tty: $!";
Так что кажется, что невозможно переопределить поведение
<>
для чтения из строки путем измененияSTDIN
.Но вместо использования нулевого дескриптора файла
<>
в вашем цикле, если вы могли бы вместо этого использовать... тогда сработало бы переопределение
STDIN
для дескриптора строкового файла:use strict; use warnings; my $str = "hello\n"; open my $fh, "<", \$str or die "Could not open string file handle: $!"; { local *STDIN = $fh; while (
) { print; } } close $fh; my $line = ; print "Terminal input: ", $line; Редактировать :
Следующее также, кажется, работает:
local *ARGV = $fh; while (<>) { print; }