Почему открытые вызовы с тремя аргументами с автообновленными файловыми дескрипторами - лучшая практика 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
, но я не могу вспомнить.
Ответы
Ответ 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 не устарел, он устарел.