Ответ 1
$fh
не устанавливается на нулевое значение, оно устанавливается в GLOB
, как показывает ваш код. Это отличается от того, что возвращает open
, поэтому идиома
open(...) or die ... ;
или
unless(open(...)) {
...
}
Следующий (не очень Perl-ish) код
#!/usr/bin/perl
if (! -e "mydir/")
{
print "directory doesn't exist.\n";
}
open (my $fh, ">", "mydir/file.txt");
if ($fh)
{
print "file opened.\n";
print $fh;
print $fh "some text\n" or die "failed to write to file.\n";
close ($fh);
}
else
{
print "failed to open file.\n";
}
выводит результат, такой как
directory doesn't exist.
file opened.
failed to write to file.
GLOB(0x...some-hex-digits...)
Почему $fh не эквивалентен false после открытого вызова? Поскольку mydir/не существует, я ожидаю, что попытка открыть файл для отказа.
Я получаю похожие результаты, если каталог и файл существуют, но файл доступен только для чтения.
Я пробовал это с Perl 5.10.1 на Windows 7 x64 и с Perl 5.10.0 на Linux-версии Fedora-11.
Я предполагаю, что мой тест дескриптора файла неправильный. Я пробовал это без везения. Я ожидаю, что это будет что-то очевидное, но любые подсказки или ссылки будут очень оценены.
Спасибо, Роб.
$fh
не устанавливается на нулевое значение, оно устанавливается в GLOB
, как показывает ваш код. Это отличается от того, что возвращает open
, поэтому идиома
open(...) or die ... ;
или
unless(open(...)) {
...
}
open
возвращает ненулевое значение при успешном завершении, а значение "ложное" при ошибке. Идиома, которую вы ищете,
if (open my $fh, '>', $file) {
# open was successful
} else {
# open failed - handle error
}
Если первый аргумент ($fh
) равен undefined (как и в этом случае), open
инициализирует его до некоторого произвольного значения (см. Symbol::genysm
), прежде чем он попытается открыть файл. Таким образом, $fh
будет всегда быть "истинным", даже если вызов open
завершился с ошибкой.
От perldoc:
Open возвращает ненулевое значение при успешном завершении, а значение undefined.
Часто используемая идиома
open my $fh, '<', $filename or die $!;
Конечно, вы можете сделать что-то другое, чем просто die
.
В дополнение к объяснениям в других ответах:
Ознакомьтесь с модулем autodie, который поставляется с perl 5.10.1 и выше (и доступен отдельно от CPAN).