Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does opening an undef not fail?

Tags:

perl

undef

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?

like image 887
Chas. Owens Avatar asked Apr 20 '17 14:04

Chas. Owens


People also ask

How do you know if something is undefined?

In a JavaScript program, the correct way to check if an object property is undefined is to use the typeof operator. If the value is not defined, typeof returns the 'undefined' string.

Why use typeof to check undefined?

typeof operator and undefined One reason to use typeof is that it does not throw an error if the variable has not been declared. However, there is another alternative. JavaScript is a statically scoped language, so knowing if a variable is declared can be read by seeing whether it is declared in an enclosing context.

How do I disable no undef ESLint?

You can disable ESLint for a given line using a // eslint-disable-line comment. For example, the below code would cause ESLint to complain because of the no-use-before-define rule if you remove the eslint-disable-line comment. A eslint-disable-line comment disables all ESLint rules for a given line.

Can not read property then of undefined?

TypeError - Cannot read property 'then' of undefined is thrown when the caller is expecting a Promise to be returned and instead receives undefined . Let's consider the above examples. In Example 1, the getTaxAmount(price, taxRate) function, when called, should have returned a Promise that resolves to a value of 12 .


1 Answers

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
like image 187
Chas. Owens Avatar answered Nov 08 '22 09:11

Chas. Owens