назначить конкретное значение Perl STDIN - PullRequest
0 голосов
/ 03 марта 2019

Я выполняю тест и мне нужно присвоить STDIN определенное значение в коде Perl.

Так что вместо чтения со стандартного ввода вот так:

#myperl.pl
#!//usr/bin/env perl
#
while (<>) {
print;
}

# echo hello | ./myperl.pl
hello

Я могу простосделать это:

#myperl.pl
#!//usr/bin/env perl
#
<STDIN> = "hello";
while (<>) {
print;
}

./myperl.pl
# hello

Конечно, текст hello может быть несколькими строками в реальном сценарии тестирования.

1 Ответ

0 голосов
/ 03 марта 2019

Согласно 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...