Почему я должен использовать ‹ARGV› или ‹› вместо ‹STDIN› в Perl?

Цитата из Perl::Critic::Policy::InputOutput::ProhibitExplicitStdin

Perl имеет полезный волшебный дескриптор файла, называемый * ARGV, который проверяет командную строку и, если есть какие-либо аргументы, открывает и читает их как файлы. Если аргументов нет, * ARGV ведет себя как * STDIN. Это почти всегда то, что вам нужно, если вы хотите создать программу, которая читает из STDIN. Это часто записывается в одной из следующих двух эквивалентных форм:

while (<ARGV>) {
  # ... do something with each input line ...
}
# or, equivalently:
while (<>) {
  # ... do something with each input line ...
}
  • Это «просто соглашение» или есть веские причины не использовать <STDIN>?

Я чувствую, что <STDIN> делает намерения моего кода более ясными, чем использование <> или <ARGV>.

Поток моего кода выглядит так

my @inp = <STDIN>;
my $len = $inp[0];

...

for(my $i = 0; $i < ($len + 0); $i++) {
    my @temp = split (' ', $inp[$i]);
    ...
}

person Lazer    schedule 19.09.2010    source источник


Ответы (2)


Это потому, что использование <ARGV> позволит пользователям либо указывать файлы для чтения в качестве аргументов, либо передавать данные в стандартный ввод без указания аргументов. Если вы используете <STDIN>, работать будет только трубопровод.

Конечно, вам решать, думаете ли вы, что люди хотели бы иметь возможность указывать файлы в качестве аргументов командной строки, но это то, что поддерживают многие программы, поэтому, возможно, стоит подумать.

person Matti Virkkunen    schedule 19.09.2010
comment
Спасибо. Если это единственная причина, мне кажется, <STDIN> лучше. - person Lazer; 19.09.2010
comment
@Lazer: это не лучше, это накладывает ограничения на способы использования программы. Зачем это делать без надобности? - person Ether; 19.09.2010
comment
Perl :: Critic основан на книге Perl Best Practices, в которой просто говорится: Избегайте использования * STDIN, если вы на самом деле это не имеете в виду. Приведенное обоснование - это более длинная версия вышеприведенного ответа. Если вы действительно имеете в виду, что подойдет только STDIN, аргументы командной строки не принимаются - тогда используйте явный STDIN. - person jmanning2k; 21.09.2010

Вы используете тот, который делает то, что вы хотите. См. perlvar для объяснения ARGV дескриптора файла. ARGV также читает из имен файлов, которые вы указываете в командной строке. Может быть, вам нужна эта функция, а может, и нет.

И вам не нужно делать то, что говорит Perl :: Critic. Многие из этих политик являются мнением небольшой группы людей. Если вы хотите только читать из STDIN явно, это то, что вам нужно сделать. Люди, пишущие политику критиков, не говорят, что вам нужно делать. Задавать любой подобный вопрос в большинстве случаев бессмысленно без контекста его применения. Общие правила - это просто общие правила, и они не работают, когда речь идет о конкретных случаях.

Я не уверен, почему вы думаете, что ваши намерения более ясны с STDIN, потому что вы не сообщили нам о своем намерении. Код почти никогда не говорит сам за себя, потому что мы склонны кодировать решение, а не формулировать проблему. Решение может быть неправильным.

В вашем случае я думаю, что этот код более понятен, потому что он написан на Perl, а не на диалекте C, который вы используете :)

 chomp( my $length = <STDIN> );

 my $count = 0;
 while ( <STDIN> ) {
     last if $count++ > $lines_to_read; 

     my @temp = split ' ';
     ...;
     }
person brian d foy    schedule 19.09.2010