Если то, что вы пытаетесь сделать, это избежать выхода из программы при возникновении ошибки открытия файла, опуская die
не правильный подход. die
- механизм исключения Perl; тот факт, что он прерывает программу по умолчанию, является случайным, а не фундаментальным, свойством. Если вы предоставляете обработчик исключений, вы сохраняете контроль. Правильный подход заключается в том, чтобы поймать исключение и выполнить очистку в блоке finally
.
use 5.10.0;
use Try::Tiny;
my ($infile, $FH);
try {
open $infile, '<', 'infile.txt' or die "Can't open infile";
try {
open $FH, '>', 'file.txt' or die "Can't open outfile";
my $line = <$infile>;
print $FH $line;
say 'Cleaning up $FH';
close $FH;
} finally {
say 'Cleaning up $infile';
close $infile;
} catch {
die $_;
};
} catch {
die $_;
};
Так что если open $infile ...
терпит неудачу, die
к catch
блок, который redies и ликвидирует сценарий. Но как только мы открыли $infile
, если open $FH
терпит неудачу, умрите в блок catch, который также прерывает программу, но сначала произойдет close $infile
. Файловые дескрипторы - не лучшие примеры ресурсов для очистки до выхода программы, потому что интерпретатор автоматически закрывает файлы, но основная идея есть.
Если вам не нравятся вложенные блоки try
, вы можете добиться такого же эффекта, проверив, какое исключение вызвало блокировку блока и решение о том, какая очистка необходима на основе этого. Это немного более хрупкий, но еще более надежный, чем все, что упоминается goto
.
Пожалуйста, не используйте Barewords 'FH' или 2 Аргумент путь открыт. ВСЕГДА используйте 'open my $ fh, '>', 'file.txt''. Это безопаснее, потому что Barewords являются глобальными. Также с возможностью открытия (чтение, добавление, письмо, ..). Когда вы используете переменную для имени файла, она может начинаться с чего-то ненадежного, сомнительного (например, Pipe ...) =) –
Пожалуйста, никогда не делайте подобные заявления. То, что он делает это прекрасно, во многих ситуациях. – tchrist