Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

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 pondering the Monastery: (5)
As of 2018-05-27 00:19 GMT
Find Nodes?
    Voting Booth?