[Israel.pm] Correct way of taking a slice of a hash reference

Peter Gordon peter at pg-consultants.com
Mon Jan 21 01:30:01 PST 2008


So shouldn't there be an option to allow %$q and @$q to auto-vivify? 


> On Mon, 2008-01-21 at 01:14 -0800, Yitzchak Scott-Thoennes wrote:
> On Mon, Jan 21, 2008 at 10:59:52AM +0200, Peter Gordon wrote:
> > This is a bit off topic - but anyway ....
> 
> Seems on topic to me?
> 
> > Can someone explain, what appears to me to be bizarre behaviour.
> >
> > Normally, Perl won't produce runtime fatal errors if the syntax is
> > correct.
> 
> Yes, it does; all the time.  Particularly with references.
> 
> > Why can't the two lines marked below just return undef.
> 
> I'd expect an empty list, if anything.  undef would be very wrong.
> 
> > The failure on @$q is particularly irritating. If a reference to an
> > array is passed and the value happens to be undef because there were no
> > entries, you need to either check that the value is a reference to an
> > array, or to do an eval. Good programming practice would say the the
> > original value should be initialized correctly. But I would prefer Perl
> > to just me undef.
> >
> > And if you are going to argue that this is correct behaviour, then why
> > does $s->{aaa} and co work?
> >
> > use strict ;
> >
> > my $s ;
> > my @t = %$s ; # <-- This causes a fatal error
> > my $t1 = $s->{aaa} ; # This works
> >
> > my $q ;
> > my @w = @$q ; <-- This causes a fatal error
> > my $t2 = $q->[10] ; # This works
> 

> Basically, some ways of using a reference will promote ("vivify")
> undef to a reference of the correct type, and some will not.
> Mostly, the division is in whether you are potentially modifying
> the referred-to structure or not.  Specifying a hash key or array
> index potentially creates it, so counts as modifying (even though
> in the simple case you show, no modification would take place,
> element dereferencing in general *may* modify).
> 
> You can just initialize your variable to start with:
> 
> my $s = {};
> my $q = [];
> 
> or check if it is undef and, if so, provide a suitable empty hash or
> array:
> 
> my @t = %{$s || {}};
> my @w = @{$q || []};
> 
> or even initialize it on the fly:
> 
> my @t = %{$s ||= {}};
> my @w = @{$q
> 
> 
> _______________________________________________
> Perl mailing list
> Perl at perl.org.il
> http://perl.org.il/mailman/listinfo/perl




More information about the Perl mailing list