При открытии файла в Perl, как я могу автоматически использовать STDIN / OUT, если имя файла "-"? - PullRequest
4 голосов
/ 06 апреля 2010

У меня есть Perl-программа, которая принимает аргументы входного и выходного файлов, и я хотел бы поддержать соглашение об использовании "-" для указания стандартного ввода-вывода.Проблема в том, что я не могу просто открыть имя файла, потому что open(my $input, '<', '-') открывает файл с именем -, а не стандартный ввод.Поэтому я должен сделать что-то вроде этого:

my $input_fh;
if ($input_filename eq '-') {
    # Special case: get the stdin handle
    $input_fh = *STDIN{IO};
}
else {
    # Standard case: open the file
    open($input_fh, '<', $input_filename);
}

И аналогично для выходного файла.Есть ли способ сделать это без тестирования для специального случая сам?Я знаю, что мог бы взломать дескриптор файла ARGV, чтобы сделать это для ввода, но это не сработает для вывода.

Редактировать: мне сообщили, что форма с 2 аргументами open на самом деле делает чудоЯ ищу.К сожалению, он также делает некоторую творческую интерпретацию, чтобы отделить имя файла от режима во втором аргументе.Я предполагаю, что форма с тремя аргументами open на 100% свободна от магии - она ​​всегда открывает файл точный , который вы ему сообщаете.Я спрашиваю, могу ли я иметь единственное исключение для "-", все еще обрабатывая каждое другое имя файла однозначно.

Должен ли я просто вставить свой код сверху в подпрограмму / модуль и прекратить ныть?

Ответы [ 2 ]

4 голосов
/ 06 апреля 2010

Вместо этого используйте форму с двумя аргументами:

open ($input_fh, "< " . $input_filename);

С man perlfunc:

В форме с двумя аргументами (и с одним аргументом) открывается "'-'" STDIN и открытие "'> -'" открывает STDOUT.

Обратите внимание, что режим < является необязательным в форме с двумя аргументами, поэтому "< -" совершенно допустим.

0 голосов
/ 09 апреля 2010

Я думаю, что нашел то, что искал. Есть отличный модуль с именем IO::All, который делает то, что я хочу, и даже больше.

Для Debian / Ubuntu / подобных пользователей пакет называется libio-all-perl. Я хотел сделать это кликабельной ссылкой на «apt: libio-all-perl», но, видимо, здесь разрешены только ссылки http.


Редактировать

Также есть Iterator::Diamond, который реализует настраиваемую магию, о которой я прошу. Он предназначен для замены оператора "101" <>, но он, вероятно, будет делать то, что я спрашиваю, если вызывается только с одним файлом (предположительно, с некоторыми издержками, но кого это волнует?).

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