Add a test for #16431, and document Dave's campaign
Jarkko Hietaniemi [Mon, 6 May 2002 13:29:22 +0000 (13:29 +0000)]
against localised hash element bugs.

p4raw-id: //depot/perl@16432

pod/perldelta.pod
t/op/tie.t

index 5e3ab41..920d74e 100644 (file)
@@ -544,6 +544,11 @@ errors so consider starting laundering now.
 
 =item *
 
+Tied hash interfaces are now required to have the EXISTS method
+(either own or inherited).
+
+=item *
+
 If tr/// is just counting characters, it doesn't attempt to
 modify its target.
 
@@ -1928,6 +1933,40 @@ Fixed numerous memory leaks, especially in eval "".
 
 =item *
 
+Localised tied variables no more leak memory
+
+    use Tie::Hash;
+    tie my %tied_hash => 'Tie::StdHash';
+
+    ...
+
+    # Used to leak memory every time local() was called,
+    # in a loop this added up.
+    local($tied_hash{Foo}) = 1;
+
+=item *
+
+Localised hash elements are correctly unlocalised to not to exist,
+if that's what they where.
+
+
+    use Tie::Hash;
+    tie my %tied_hash => 'Tie::StdHash';
+
+    ...
+
+    # Nothing has set the FOO element so far
+
+    { local $tied_hash{FOO} = 'Bar' }
+    
+    # Here the FOO element would have been C<undef>,
+    # but no more so. 
+
+As a side effect of this fix, tied hash interfaces B<must> define
+the EXISTS method.
+
+=item *
+
 mkdir() now ignores trailing slashes in the directory name,
 as mandated by POSIX.
 
@@ -2846,18 +2885,6 @@ some output may appear twice.
 
 Use XML::Parser 2.31 or later.
 
-=head2 Localising a Tied Variable Leaks Memory
-
-    use Tie::Hash;
-    tie my %tie_hash => 'Tie::StdHash';
-
-    ...
-
-    local($tie_hash{Foo}) = 1; # leaks
-
-Code like the above is known to leak memory every time the local()
-is executed.
-
 =head2 z/OS (OS/390)
 
 z/OS has rather many test failures but the situation is actually
index 9a65155..f8f2322 100755 (executable)
@@ -202,3 +202,12 @@ EXPECT
 tie FH, 'main';
 EXPECT
 
+########
+# correct unlocalisation of tied hashes (patch #16431)
+use Tie::Hash ;
+tie %tied, Tie::StdHash;
+{ local $hash{'foo'} } print "exist1\n" if exists $hash{'foo'};
+{ local $tied{'foo'} } print "exist2\n" if exists $tied{'foo'};
+{ local $ENV{'foo'}  } print "exist3\n" if exists $ENV{'foo'};
+EXPECT
+