Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Dereferencing undef as an array: Bug or WAD?

by BrowserUk (Patriarch)
on Jun 04, 2008 at 05:19 UTC ( [id://690064]=perlquestion: print w/replies, xml ) Need Help??

BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

Update: WAD := Working As Designed.

Why is this legal (no error produced):

C:\test>perl -Mstrict -wle" my $r = undef; my @x = map{ $_ } @{ $r }"

But this not?

C:\test>perl -Mstrict -wle" my $r = undef; my @x = @{ $r }" Can't use an undefined value as an ARRAY reference at -e line 1.

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: Dereferencing undef as an array: Bug or WAD?
by ikegami (Patriarch) on Jun 04, 2008 at 05:24 UTC

    lvalue vs rvalue. When an undefined value is dereferenced to be used as an lvalue, it gets autovivified.

    >perl -Mstrict -wle"my $r; my @x; @x=@$r; print $r" Can't use an undefined value as an ARRAY reference at -e line 1. >perl -Mstrict -wle"my $r; my @x; @$r=@x; print $r" ARRAY(0x225280)

    map appears to expect an lvalue, possibly because it aliases.

    >perl -Mstrict -wle"my $r; my @x = map{ $_ } @{ $r }; print $r" ARRAY(0x225258)

    More examples where aliasing is involved:

    >perl -Mstrict -wle"my $r; my @x; for(@$r){} print $r" ARRAY(0x225280) >perl -Mstrict -wle"my $r; my @x; sub{}->(@$r); print $r" ARRAY(0x225280)

    Update: Oops, fixed mention of rvalue where I meant lvalue. Re-ordered post for better readability. Added extra examples.

Re: Dereferencing undef as an array: Bug or WAD? (autovivification)
by almut (Canon) on Jun 04, 2008 at 10:02 UTC

    Not directly related to your observation, but maybe still interesting in the wider context of autovivifying things...  While trying to get some third-party code to run under strict, I recently stumbled across the phenomenon that something like

    if (%$href) { print "has elements" }

    produces "Can't use an undefined value as a HASH reference" when $href is undefined (under strict, that is, works fine without strict), while

    my @keys = keys %$href; my @vals = values %$href; while (my ($key, $val) = each %$href) { ... }

    all work fine under strict, because they autovivify the hash.

    (The former case - which could also be written as scalar %$href - is supposed to test if the referenced hash contains elements, with the special case that the hash doesn't exist at all being semantically equivalent to "has no elements").

    The explanation based on aliases being created (implying lvalue-ness) only holds partially here: evaluating the hash in scalar context presumably does not create aliases (so the behaviour is "as expected"); values does create aliases (so that's as expected, too); but keys does not create aliases, at least not in a way that you could say

    for (keys %$href) { $_ = "foo"; }

    and have the keys in the hash be modified.  Still, it obviously autovivifies.

Re: Dereferencing undef as an array: Bug or WAD?
by casiano (Pilgrim) on Jun 04, 2008 at 09:07 UTC
    But why is $r used as a lvalue here?
    C:\test>perl -Mstrict -wle" my $r = undef; my @x = map{ $_ } @{ $r }"
    I would say it is being used as an rvalue?
    Is it because map code can change the list argument as in:
    DB<25> use strict; my @a = 0..5; my @b = map { $_ = $_*$_ } @a; print + "@a\n@b" 0 1 4 9 16 25 0 1 4 9 16 25

    Many Thanks

    Casiano

      Is it because map code can change the list argument...

      That is the implication of ikegami's post.

      For a definitive answer we'd need someone from p5p to comfirm that.

      Update: That said, if it was being autovivified in the normal sense, you'd expect that either it would persist, or at least values derived from it to persist, but neither is the case:

      C:\test>perl -Mstrict -wle "my $r= undef; my @x= map ++$_,@{$r};print qq[[@$r]\n[@x]]" [] []

      I think there is a bug there somewhere, but it might be hard to define.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        It does persist—you've autovivified $r as a reference to an array, but that array is still empty:

        % perl -Mstrict -wle 'my $r = undef; map ++$_, @$r; print $r;' ARRAY(0x10116180)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://690064]
Approved by prasadbabu
Front-paged by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2025-03-23 23:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When you first encountered Perl, which feature amazed you the most?










    Results (63 votes). Check out past polls.