В чем различия между этими «открытыми» форматами - PullRequest
6 голосов
/ 30 марта 2011

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

open( INPUTFILE, "< $input_file" ) || die "Can't open $input_file: $!";

Несколько дней назад я увидел в ТАКом ответе на эту форму:

open( $input_file, "<", $input_file ) || die "Can't open $input_file: $!";

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

Должен ли я перейти на «новый» формат? Есть ли у него какие-то преимущества или у «старого» формата есть недостатки?

Ответы [ 3 ]

11 голосов
/ 30 марта 2011

Вы должны использовать версию с тремя аргументами, потому что она защищает от файлов с сумасшедшими именами. Учтите следующее:

my $file = "<file.txt";
open( INPUTFILE, "< $file" ) or die "$!";

Это будет интерполировать как:

open( INPUTFILE, "< <file.txt" ) or die "$!";

... означает, что вы действительно откроете файл с именем file.txt вместо одного с именем <file.txt.

Теперь для дескриптора файла вы хотите использовать лексический дескриптор файла:

open( my $fh, "<", $file.txt ) or die "$!";

Причина этого в том, что когда $fh выходит из области видимости, файл закрывается. Кроме того, другой тип файлового дескриптора (я не помню, как он называется) имеет global scope. Программисты не настолько изобретательны, так что, вероятно, вы назовете свой дескриптор файла INPUTFILE или FH или FILEHANDLE. Что произойдет, если кто-то еще сделал то же самое, назвал свой дескриптор файла INPUTFILE в модуле, который вы используете? Ну, они оба действительны, и один забивает другой. Какой из них раздолбает? Кто знает. Это до заказа, когда они открыты. И повторюсь? А что произойдет, если другой программист открыл INPUTFILE, но фактически открыл его для записи? Конец света, друг мой, конец света.

Если вы используете лексический файловый дескриптор ($fh), вам не нужно беспокоиться об окончании миров, потому что даже если другой программист вызывает его $fh, переменная область действия защищает вас от ударов.

Так что да, всегда используйте форму с тремя аргументами open() с лексическими дескрипторами файлов. Спасти мир.

3 голосов
/ 30 марта 2011

Разница между формой с двумя аргументами open и формой с тремя аргументами связана с тем, как обрабатывается имя файла, когда оно содержит специальные символы.Например, в случае открытия двух аргументов, если имя файла содержит символ | или ряд других специальных символов, файл будет открыт с помощью оболочки.Таким образом, с двумя открытыми аргументами можно написать что-то вроде этого:

 open my $file, 'rm -rf * |';

, и Perl с радостью откроет канал для вывода rm, в то время как он удалит вашу систему.

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

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

Вы можете получить все подробности открытия на странице руководства .

1 голос
/ 30 марта 2011

С учебник по Perl

Существует также версия open с тремя аргументами, которая позволяет помещать специальные символы перенаправления в их собственные аргументы:

open( INFO, ">", $datafile ) || die "Can't create $datafile: $!";

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

Так что версия open с тремя аргументами является наиболее безопасной для использования.

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