sub.t: To-do test for recursive shared-hash-keys TARGs
authorFather Chrysostomos <sprout@cpan.org>
Sat, 15 Jun 2013 18:41:57 +0000 (11:41 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 26 Jul 2013 06:47:58 +0000 (23:47 -0700)
This is only buggy under ithreads.

sub a {
  for (${\""}.${\""}) {
    $_ = $_[0] || __PACKAGE__;
    print "$_\n";
    a("road") unless $_[0];
    print "$_\n";
  }
}
a();

The outer call sets the scalar returned by ${\""}.${\""} to the cur-
rent package name.

The inner call sets it to "road".

Each call prints it twice, the outer call surrounding the inner call.
The output in 5.10-5.18 is:

main
road
road
road

because the inner call is clobbering the same scalar.  If __PACKAGE__
is changed to "main", it works, and prints

main
road
road
main

(as the script above also prints in 5.8.8).

t/op/sub.t

index c4121df..e00f26f 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan( tests => 16 );
+plan( tests => 17 );
 
 sub empty_sub {}
 
@@ -85,3 +85,26 @@ undef *foo;
 undef *bar;
 print "ok\n";
 end
+
+# The outer call sets the scalar returned by ${\""}.${\""} to the current
+# package name.
+# The inner call sets it to "road".
+# Each call records the value twice, the outer call surrounding the inner
+# call.  In 5.10-5.18 under ithreads, what gets pushed is
+# qw(main road road road) because the inner call is clobbering the same
+# scalar.  If __PACKAGE__ is changed to "main", it works, the last element
+# becoming "main".
+my @scratch;
+sub a {
+  for (${\""}.${\""}) {
+    $_ = $_[0];
+    push @scratch, $_;
+    a("road",1) unless $_[1];
+    push @scratch, $_;
+  }
+}
+a(__PACKAGE__);
+require Config;
+$::TODO = "not fixed yet" if $Config::Config{useithreads};
+is "@scratch", "main road road main",
+   'recursive calls do not share shared-hash-key TARGs';