Why does opening an undef not fail?

This code dies as I expect it to:

use strict;
use warnings;

open my $fh, "<", "" or die $!;

Но это не так:

use strict;
use warnings;

open my $fh, "<", undef or die $!;

Что здесь происходит?

1 ответ

Функция open имеет множество маленьких причуд, вот одна из них:

В особом случае форма с тремя аргументами с режимом чтения / записи и третьим аргументом "undef":

open(my $tmp, "+>", undef) or die ...

открывает дескриптор файла для анонимного временного файла. Также использование "+<" работает для симметрии, но вы действительно должны сначала записать что-нибудь во временный файл. Вам нужно будет искать (), чтобы сделать чтение.

Хотя, как отмечается в комментариях, в документации настоятельно рекомендуется, чтобы это происходило только для режимов "+<" и ">+". Я считаю, что это код, который реализует поведение. Не проверяет режим. Я не знаю, является ли это ошибкой или нет, но сообщу после разговора с P5P.

PerlIO *
PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
             int imode, int perm, PerlIO *f, int narg, SV **args)
{
    if (!f && narg == 1 && *args == &PL_sv_undef) {
        if ((f = PerlIO_tmpfile())) {
            if (!layers || !*layers)
                layers = Perl_PerlIO_context_layers(aTHX_ mode);
            if (layers && *layers)
                PerlIO_apply_layers(aTHX_ f, mode, layers);
        }
    }

Очевидно, документация была исправлена ​​в blead perl в ноябре:

diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 18bb4654e1..1e32cca6dd 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -4405,9 +4405,9 @@ argument being L<C<undef>|/undef EXPR>:

     open(my $tmp, "+>", undef) or die ...

-opens a filehandle to an anonymous temporary file.  Also using C<< +< >>
-works for symmetry, but you really should consider writing something
-to the temporary file first.  You will need to
+opens a filehandle to a newly created empty anonymous temporary file.
+(This happens under any mode, which makes C<< +> >> the only useful and
+sensible mode to use.)  You will need to
 L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> to do the reading.

 Perl is built using PerlIO by default.  Unless you've
Другие вопросы по тегам