Я бы написал это как
my $LOGPATH = $ENV{DATA_OU};
my $LOGFILE = "cdj_rep.test.rpt";
my $path = "$LOGPATH/test1/work/$LOGFILE";
open my $fh, ">", $path or do {
warn "$0: open $path: $!";
return;
};
close $fh or warn "$0: close $path: $!";
Поместите весь путь в $path
, чтобы вам не приходилось повторять его несколько раз, и если вам когда-нибудь понадобится его изменить, вы можете сделать это в одном месте.
При вызове open
используется лексический дескриптор файла (my $fh
), а не дескриптор голого слова. Это хорошая привычка для развития, потому что передача $fh
подпрограммам или вставка их в структуры данных имеет тенденцию быть более естественной синтаксически.
Он также использует форму с тремя аргументами open
, поэтому вам не нужно беспокоиться о символах в пути, который интерпретируется специально. В контексте вашего кода это может показаться не таким уж большим делом, но это еще одна хорошая привычка для развития.
Распространенной идиомой для проверки успешности open
является
open my $fh, "<", $path
or die "$0: open $path: $!";
Можно использовать if (!open ...
или unless (open ...
, но с лексическим дескриптором файла вам нужно беспокоиться о проблемах с областями видимости. Похоже, вы используете проверку в качестве защиты, поэтому запись open or ...
оставляет дескриптор файла в области видимости, когда он действительно успешен. Вы хотите, чтобы два оператора выполнялись в случае сбоя, поэтому вам нужно заключить их в do { ... }
, как указано выше.
Также обратите внимание на содержание сообщения об ошибке, переданного warn
:
- программа с ошибкой (
$0
)
- что он пытался сделать (
open $path
)
- и почему это не удалось (
$!
)
Операторы warn
и die
отправляют свои выходные данные в стандартную ошибку, что позволяет гибко перенаправлять сообщения об ошибках в другом месте.
Наконец, когда вы close
обрабатываете файл, который вы создали для записи или добавления, вы должны проверить, не получается ли он, что может произойти, например, при ошибке ввода-вывода.