Подтвердить что ты не робот

Почему открытые вызовы с тремя аргументами с автообновленными файловыми дескрипторами - лучшая практика Perl?

У меня есть два вопроса о функции Perl open:

1) Я, кажется, помню из Perl Best Practices, что версия с тремя аргументами open лучше, чем две версии аргументов, например

open(OUT, '>>', $file);

против.

open(OUT, ">>$file");

Почему? Я пытался сказать кому-то, чтобы использовать версию с тремя аргументами на днях, но, похоже, ничего не мог поддержать.

2) Я также помню, что автовивируемые дескрипторы файлов были предпочтительнее дескрипторов дескрипторов (они называли что-то другое)? А также не мог вспомнить, почему, например,

open(my $out, '>>', $file);

против.

open(OUT, '>>', $file);

Это вещь strict? Кажется, я помню, что имел возможность использовать OUT с strict, но я не могу вспомнить.

4b9b3361

Ответ 1

  • Использование типовglobs для дескрипторов файлов (например, OUT) не является хорошей идеей, поскольку они являются глобальными для всей вашей программы - вы должны быть уверены, что никакая другая процедура, включая модули в модулях, не использует одно и то же имя (в том числе в будущее).
  • Использование двунаправленной формы open предоставляет вашему приложению неправильное поведение, вызванное переменными, содержащими специальные символы, например my $f; open $f, ">$some_filename"; подвергается ошибке, где $some_filename, содержащий ведущий >, изменяет поведение программы.

Использование формы с тремя аргументами позволяет избежать этого, разделив режим и имя файла на отдельные аргументы, где они не могут вмешиваться.

Более того, использование формы много аргументов с помощью труб - очень хорошая идея:

open $pipe, '|-', 'sendmail', '[email protected]';

Лучше, чем делать все как одну строку - это позволяет избежать возможной инъекции оболочки и т.д.

Ответ 2

Схватка # 2:

OUT - это глобальный дескриптор файла, и использование его предоставляет вам коварные ошибки следующим образом:

sub doSomething {
  my ($input) = @_;
  # let compare $input to something we read from another file
  open(F, "<", $anotherFile);
  @F = <F>; 
  close F;
  &do_some_comparison($input, @F);
}

open(F, "<", $myfile);
while (<F>) {
    &doSomething($_);   # do'h -- just closed the F filehandle
}
close F;

Ответ 3

Один аспект, который следует иметь в виду, состоит в том, что форма с двумя аргументами нарушена. Рассмотрим файл с именем "abc" (то есть имя файла с ведущим пробелом). Вы не можете открыть файл:

open my $foo, ' abc' or die $!;
open my $foo, '< abc' or die $!;
open my $foo, '<  abc' or die $!;
# nothing works

Пробел удаляется, поэтому файл больше не может быть найден. Такой сценарий очень маловероятен, но определенно проблема. Форма три-arg невосприимчива к этому:

open my $foo, '<', ' abc' or die $!;
# works

Этот поток от perlmonks так же хорош, как и любая проблема. Просто имейте в виду, что в 2001 году форма с тремя аргументами по-прежнему считалась новой и, следовательно, не пригодна для переносимого кода, поскольку программы Perl умирают с синтаксической ошибкой, если они работают на интерпретаторе 5,005. Это уже не так: perl 5.005 не устарел, он устарел.