Как я могу сказать функции Perl, которая берет файл для чтения из специального дескриптора ARGV? - PullRequest
7 голосов
/ 29 октября 2010

В perldoc perlvar я прочитал это:

Обратите внимание, что в настоящее время "ARGV" имеет магический эффект только в операторе "<>";в другом месте это просто простой файловый дескриптор, соответствующий последнему файлу, открываемому «<>».В частности, передача «* ARGV» в качестве параметра функции, которая ожидает дескриптор файла, может не заставить вашу функцию автоматически читать содержимое всех файлов в @ ARGV.

Итак, как могу передать *ARGV (или что-то похожее на него) в качестве параметра функции, ожидающей дескриптор файла, и заставить эту функцию читать все файлы в @ARGV?

Ответы [ 3 ]

12 голосов
/ 29 октября 2010

Идите прямо и передайте *ARGV typeglob или \*ARGV, его ссылку. Просто убедитесь, что функция, в конечном итоге использующая ее, делает это с помощью оператора <$fh> или readline($fh), ее базового функционального эквивалента.

Проблема, затронутая в процитированном отрывке из man-страницы perlvar, просто пытается напомнить вам, что вы не сможете получить ARGV magic open для запуска, если вы используете другое чтение механизм, чем readline на ручке, например read, sysread или getc.

Запустите это, чтобы доказать себе, что это работает:

sub mycat {
    my $fh = shift;
    print "$ARGV $.: $_" while <$fh>;
}
mycat(*ARGV);

Поместите это в файл, затем запустите его с несколькими аргументами файла:

% perl mycat ./mycat //`pwd`/mycat ~/mycat
./mycat 1: sub mycat {
./mycat 2:     my $fh = shift;
./mycat 3:     print "$ARGV $.: $_" while <$fh>;
./mycat 4: } 
./mycat 5: mycat(*ARGV);
///home/tchrist/mycat 6: sub mycat {
///home/tchrist/mycat 7:     my $fh = shift;
///home/tchrist/mycat 8:     print "$ARGV $.: $_" while <$fh>;
///home/tchrist/mycat 9: } 
///home/tchrist/mycat 10: mycat(*ARGV);
/home/tchrist/mycat 11: sub mycat {
/home/tchrist/mycat 12:     my $fh = shift;
/home/tchrist/mycat 13:     print "$ARGV $.: $_" while <$fh>;
/home/tchrist/mycat 14: } 
/home/tchrist/mycat 15: mycat(*ARGV);

См? Работает нормально.

1 голос
/ 29 октября 2010

Вы можете повторно отправить <> при переборе перегруженного объекта:

{package ReadARGV;
    sub new {bless []}
    use overload '<>' => sub {<>};
}

sub reader {
    my $fh = shift;
    local $_;
    print while <$fh>;
}

reader(ReadARGV->new);

Пакет ReadARGV содержит простой конструктор объекта new, а затем перегружает оператор <HANDLE> для простого вызова <>.

0 голосов
/ 29 октября 2010

Вы можете подделать его с помощью cat (в системе Unix)

open FAKE_ARGV, "cat @ARGV |";
function_expecting_filehandle(*FAKE_ARGV);
...

Вы теряете часть магии ($ARGV, $.) с этим.

Я уверен, что есть способ сделать это и с привязанной файловой ручкой (см. perltie).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...