Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re^2: open undef

by morgon (Priest)
on Aug 02, 2018 at 18:13 UTC ( [id://1219722]=note: print w/replies, xml ) Need Help??


in reply to Re: open undef
in thread open undef

I am not sure if this is documented as I open the file in read-mode, where this behaviour does not make any sense at all, but nevertheless very interesting.

Can you explain then why the first case is different?

Replies are listed 'Best First'.
Re^3: open undef
by ikegami (Patriarch) on Aug 02, 2018 at 20:04 UTC

    When a Perl operator returns only true or false, it returns one of two statically-allocated scalars called &PL_sv_yes and &PL_sv_no. It's more efficient to return these than to allocate a new scalar every time.

    There's a third statically-allocated scalar: &PL_sv_undef. It's used by Perl when it needs to return undef.

    $ perl -MDevel::Peek -e'Dump(undef)' SV = NULL(0x0) at 0x2186148 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT)

    This scalar is undefined because it has no OK flags. But notice the artificially high REFCNT that prevents it from being deallocated. This tells us that Perl returned &PL_sv_undef. I shall call this "the undef", in contrast to other undefined scalars which I'll call "an undef".

    An array element that has never been allocated (e.g. because nothing was ever assigned to it, or because delete was used on it) returns the undef.

    $ perl -MDevel::Peek -e'Dump($a[0])' SV = NULL(0x0) at 0x1116148 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT)

    Otherwise, the array element itself is returned, which might be an undef.

    $ perl -MDevel::Peek -e'$a[0]=undef; Dump($a[0])' SV = NULL(0x0) at 0xc93f90 REFCNT = 1 FLAGS = ()

    The feature is meant to be triggered when you literally use undef in the code. But what it actually does is check for the undef.

    use feature qw( say ); my @a; { say open(my $fh, '<', $a[0]) ? 1 : 0; } # 1 $a[1] = undef; { say open(my $fh, '<', $a[0]) ? 1 : 0; } # 1 $a[0] = undef; { say open(my $fh, '<', $a[0]) ? 1 : 0; } # 0 delete($a[0]); { say open(my $fh, '<', $a[0]) ? 1 : 0; } # 1

    As you've discovered, this is an imperfect proxy.

      I am not really sure if I understand what you are trying to say (but it is very interesting) - so thanks for that.

      For me I am trying to figure out why perl handles the cases differently.

      My position is that what happens in the first case is the proper thing to do.

      You want to open a file for reading and you supply undef as a file-name: Error. That's how I think it should be.

      And I still cannot quite see why the cases supplied should be different.

      And there is this:

      perl -MDevel::Peek -e'Dump($ARGV[0])' SV = NULL(0x0) at 0x55a8c4978560 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT) perl -MDevel::Peek -e'Dump(undef)' SV = NULL(0x0) at 0x55923aa70560 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT)
      Both have the same high refcount, but the addresses seem to differ - why is that?

      Is this a can of worms that one should not open?

        My position is that what happens in the first case is the proper thing to do.

        The first and third case are behaving correctly. The middle one should behave like the first, but open can't tell the difference between an unallocated array element and undef (since they both return the undef).

        the addresses seem to differ - why is that?

        I believe memory addresses are varied between program runs to minimize the damage from certain types of attacks. If you did both Dump in the same run, they would have the same address.

        $ perl -MDevel::Peek -e'Dump($ARGV[0]); Dump(undef);' SV = NULL(0x0) at 0xf78148 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT) SV = NULL(0x0) at 0xf78148 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT) $ perl -MDevel::Peek -e'Dump($ARGV[0]); Dump(undef);' SV = NULL(0x0) at 0xbe6148 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT) SV = NULL(0x0) at 0xbe6148 REFCNT = 2147483639 FLAGS = (READONLY,PROTECT)
Re^3: open undef
by haukex (Archbishop) on Aug 02, 2018 at 20:35 UTC
    I am not sure if this is documented as I open the file in read-mode

    From open (emphasis mine):

    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 a newly created empty anonymous temporary file. (This happens under any mode, which makes +> the only useful and sensible mode to use.)
      Thanks.

      So it IS documented, even though it the behaviour does not really make sense.

      What a relief...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1219722]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2024-04-20 02:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found