Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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
[choroba]: Půlnoční Marie (which means Midnight Mary)
[choroba]: but the band is practically dead. We rehearse once in a year, and perform with the same frequency
[ambrus]: `quote
[ambrus]: sorry, typed in the wrong box
[LanX]: Your mother: je ne t'aime plus! ;)
[choroba]: seems lispy
[Your Mother]: Be nice! I speak that much French. Though I also like that song.
[choroba]: So, I joined Pod Černư Vrch some months ago to still have the fun. But I wouldn't call it "punk" anymore...
[LanX]: choroba deaf after one rehearsal per year ?
Discipulus .. per ear!

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (10)
As of 2017-03-24 12:31 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (301 votes). Check out past polls.