This code dies as I expect it to:
use strict;
use warnings;
open my $fh, "<", "" or die $!;
But this does not:
use strict;
use warnings;
open my $fh, "<", undef or die $!;
What is going on here?
This code dies as I expect it to:
use strict;
use warnings;
open my $fh, "<", "" or die $!;
But this does not:
use strict;
use warnings;
open my $fh, "<", undef or die $!;
What is going on here?
The open function has lots of little quirks, this is one of them:
As a special case the three-argument form with a read/write mode and the third argument being "undef":
open(my $tmp, "+>", undef) or die ...
opens a filehandle to an anonymous temporary file. Also using "+<" works for symmetry, but you really should consider writing something to the temporary file first. You will need to seek() to do the reading.
Although, as ysth notes in the comments, the documentation strongly suggests that this should only happen for "+<" and ">+" modes. I believe this is the code that implements the behavior. It does not check the mode. I do not know if this is a bug or not, but will report back after talking to 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);
}
}
Apparently, the documentation was fixed in blead perl in November:
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
+>
AND the third argument is undef
. It is just worded poorly –
Apthorp © 2022 - 2024 — McMap. All rights reserved.