2010-07-13 2 views
3

Я хочу выполнить некоторую задачу, когда файл не открывается в программе Perl ниже. Но когда я запускаю его, я получаю синтаксические ошибки. Что с этим не так?perl open file error handling

my $LOGPATH = $ENV{DATA_OU}; 
my $LOGFILE = "cdj_rep" . "." . "test" . ".rpt"; 

if ! (open(OUT,">$LOGPATH/test1/work/$LOGFILE")) { 
    print "testin"; 
    return; 
} 

close(OUT); 

ответ

9

The! нужно идти в скобках:

if (! open (out, 
+0

Большое спасибо за информацию – Arav

11

Я пишу это как

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 на субтитры или набивание их внутри структур данных имеет тенденцию быть более естественным синтаксически.

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

Общая идиома для проверки преуспевает ли open является

open my $fh, "<", $path 
    or die "$0: open $path: $!"; 

Использования if (!open ... или unless (open ... было бы хорошо, но с лексическим дескриптором, вам нужно беспокоиться о обзорных вопросах. Кажется, вы используете чек в качестве охранника, поэтому запись open or ... оставляет дескриптор файла в том объеме, в котором он достиг успеха. Вы хотите, чтобы выполнялись два оператора, если они терпят неудачу, поэтому вам необходимо обернуть их в do { ... }, как указано выше.

внимание также содержание сообщения об ошибке передается warn:

  • программа, которая была ошибка ($0)
  • , что он пытается сделать (open $path)
  • и почему он не смог ($!)

В warn и die операторы отправить их OUTP ut к стандартной ошибке, что позволяет гибко перенаправлять сообщения об ошибках в другом месте.

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

+2

Шверн говорит, что мы должны использовать 'autodie'. – 2010-07-13 02:12:11

+1

+1: хорошо написанная рекомендация для новых, лучших методов Perl open. – dawg

+0

Спасибо, что выбрасывали свет за $ 0 и $! встроенные переменные. Очень полезно для новичков вроде меня. Кроме того, не согласен ли использовать прописные FILE_HANDLES? –