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

Should perl auto vivify here?

by randian (Acolyte)
on May 27, 2012 at 05:43 UTC ( #972662=perlquestion: print w/replies, xml ) Need Help??
randian has asked for the wisdom of the Perl Monks concerning the following question:

In perl 5.14+, array functions like push can accept array refs e.g. push $arrayref, @values where they formerly only accepted arrays. If you have an undefined scalar inside a @{} wrapper, that scalar will be auto vivified into an array ref, like so: push @{$future_arrayref}, @values. Unfortunately, without the wrapper (push $future_arrayref, @values) that will fail with an error. Shouldn't that autovivify $future_arrayref?

Replies are listed 'Best First'.
Re: Should perl auto vivify here?
by Anonymous Monk on May 27, 2012 at 08:19 UTC

    Unfortunately, without the wrapper (push $future_arrayref, @values) that will fail with an error. Shouldn't that autovivify $future_arrayref?

    I don't think push should autovivify because that would be a surprise (no built-ins autovivify) and it would hide delay discovering errors (pushing onto the wrong variable).

    I feel the current documentation for push is wrong, as push doesn't really dereference anything. The new experimental feature merely saves you from manually having to dereferencing to satisfy prototypes -- push always took an array ref as an argument but required you to type  push @array instead of  push \@array and now it drops the requirement so you don't have to write  push @{$array}

    Only dereferencing in lvalue context autovivifies (more on this in Re: undefined value as an ARRAY reference sometimes ok ) and plenty of newbies complain about this already :)( see When DOESN'T "Use of uninitialized value" show up? )

    So why is this new experimental feature more than mere keystroke saving sugar? Because it doesn't autovivify. Consider this

    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump; my @foo; my $bar; silentWin( \@foo ); silentFail( $bar ); dd \@foo; dd $bar; aliasUglyWin( $bar ); dd $bar; print "bye\n"; silentWin( undef ); print "bye\n"; sub silentWin { my( $arrayref ) = @_; push $arrayref, "win"; } sub silentFail { my( $arrayref ) = @_; push @{$arrayref}, "fail"; } sub aliasUglyWin { push @{ $_[0] } , "ugly win"; } __END__ ["win"] undef ["ugly win"] bye Not an ARRAY reference ...

    aliasUglyWin() works but its ugly :)  $_[0] is aliased to $bar, so the correct variable ($bar) is autovivified

    silentFail() fails because when you copy  $_[0] to $arrayref, $arrayref is not aliased to $bar , so the wrong variable is autovivified ( not $bar)

    silentWin() saves you three keystrokes @{} and it doesn't autovivify the wrong variable but dies instead . It also changes the diagnostics message from Type of arg 1 to push must be array ... to Not an ARRAY reference

    So I don't think push should autovivify, I feel it defeats what little advantage this new experimental feature provides to the uninitiated

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://972662]
Approved by Corion
Front-paged by Eliya
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (1)
As of 2017-07-27 00:49 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (402 votes). Check out past polls.