FAQ
Author: comdog
Date: Fri Aug 29 06:29:25 2008
New Revision: 11687

Modified:
perlfaq/trunk/perlfaq4.pod

Log:
* perlfaq4: Why does passing a subroutine an undefined element in a hash create it?
+ Note that this only matters for really old Perls


Modified: perlfaq/trunk/perlfaq4.pod
==============================================================================
--- perlfaq/trunk/perlfaq4.pod (original)
+++ perlfaq/trunk/perlfaq4.pod Fri Aug 29 06:29:25 2008
@@ -2279,21 +2279,45 @@

=head2 Why does passing a subroutine an undefined element in a hash create it?

-If you say something like:
+(contributed by brian d foy)

- somefunc($hash{"nonesuch key here"});
+Are you using a really old version of Perl?

-Then that element "autovivifies"; that is, it springs into existence
-whether you store something there or not. That's because functions
-get scalars passed in by reference. If somefunc() modifies C<$_[0]>,
-it has to be ready to write it back into the caller's version.
+Normally, accessing a hash key's value for a nonexistent key will
+I<not> create the key.

-This has been fixed as of Perl5.004.
+ my %hash = ();
+ my $value = $hash{ 'foo' };
+ print "This won't print\n" if exists $hash{ 'foo' };
+
+Passing C<$hash{ 'foo' }> to a subroutine used to be a special case, though.
+Since you could assign directly to C<$_[0]>, Perl had to be ready to
+make that assignment so it created the hash key ahead of time:
+
+ my_sub( $hash{ 'foo' } );
+ print "This will print before 5.004\n" if exists $hash{ 'foo' };
+
+ sub my_sub {
+ # $_[0] = 'bar'; # create hash key in case you do this
+ 1;
+ }
+
+Since Perl 5.004, however, this situation is a special case and Perl
+creates the hash key only when you make the assignment:
+
+ my_sub( $hash{ 'foo' } );
+ print "This will print, even after 5.004\n" if exists $hash{ 'foo' };
+
+ sub my_sub {
+ $_[0] = 'bar';
+ }

-Normally, merely accessing a key's value for a nonexistent key does
-I<not> cause that key to be forever there. This is different than
-awk's behavior.
+However, if you want the old behavior (and think carefully about that
+because it's a weird side effect), you can pass a hash slice instead.
+Perl 5.004 didn't make this a special case:

+ my_sub( @hash{ qw/foo/ } );
+
=head2 How can I make the Perl equivalent of a C structure/C++ class/hash or array of hashes or arrays?

Usually a hash ref, perhaps like this:

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcvs-perlfaq @
categoriesperl
postedAug 29, '08 at 1:29p
activeAug 29, '08 at 1:29p
posts1
users1
websitelearn.perl.org...

1 user in discussion

Comdog: 1 post

People

Translate

site design / logo © 2019 Grokbase