Согласно perldoc open
:
[...] вы можете открывать файловые дескрипторы непосредственно в скалярах Perl с помощью:
open(my $fh, ">", \$variable) || ..
см. также PerlIO :: scalar .Далее, в соответствии с perldoc perlop :
Нулевой дескриптор файла <> является специальным: его можно использовать для эмуляции поведения sed
и awk
и любых другихUnix filter программа, которая принимает список имен файлов, делая то же самое для каждой строки ввода из всех них.Ввод из <>
поступает либо из стандартного ввода, либо из каждого файла, указанного в командной строке.Вот как это работает: при первом вычислении <>
проверяется массив @ARGV
, а если он пуст, $ARGV[0]
устанавливается на "-"
, что при открытии дает стандартный ввод.Массив @ARGV
затем обрабатывается как список имен файлов.
Поэтому, когда вы выполните while (<>)
, он попытается «открыть стандартный ввод» (при условии, что вы не указали аргументы командной строки, т. Е. @ARGV
пусто).На эту команду open
не влияет текущее значение переменной STDIN
, вместо этого (я полагаю) она просто сделает что-то вроде:
open ARGV, '/dev/tty' or die "open: /dev/tty: $!";
Так что кажется, что невозможно переопределитьповедение <>
для чтения из строки путем изменения STDIN
.
Но вместо использования дескриптора нулевого файла <>
в вашем цикле, если вы могли бы использовать вместо него <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 (<STDIN>) {
print;
}
}
close $fh;
my $line = <STDIN>;
print "Terminal input: ", $line;
Edit :
Кажется также работает следующее:
local *ARGV = $fh;
while (<>) {
print;
}