[svn:perlfaq] r11687 - perlfaq/trunk

[email protected] Fri, 29 Aug 2008 06:29:31 -0700 (PDT)
Newsgroups perl.cvs.perlfaq
Message-ID <[email protected]>
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: