This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Modifying ${^OPEN} changes the value of $^H:
authorFather Chrysostomos <sprout@cpan.org>
Sat, 10 Aug 2013 16:49:28 +0000 (09:49 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 11 Aug 2013 14:54:42 +0000 (07:54 -0700)
$ ./perl -le 'BEGIN { print $^H; ${^OPEN} = "a\0b"; print $^H}'
256
917760

So changing $^H back should change the value of ${^OPEN} back to undef, right?

$ ./perl -le 'BEGIN { ${^OPEN} = "a\0b"; $^H=256; print ${^OPEN}//"undef"}'
ab
$ ./perl -le 'BEGIN { ${^OPEN} = "a\0b"; $^H=256;}BEGIN{ print ${^OPEN}//"undef"}'
undef

Apparently you have to hop from one BEGIN block to another to see
the changes.

This happens because compile-time hints are stored in PL_hints (which
$^H sets) but ${^OPEN} looks in PL_compiling.cop_hints.  Setting
${^OPEN} sets both.  The contents of PL_hints are assigned to
PL_compiling.cop_hints at certain points (the start of a BEGIN block
sees the right value because newSTATEOP sets it), but the two are not
always kept in synch.

The smallest fix here is to have $^H set PL_compiling.cop_hints as
well as PL_hints, but the ultimate fix--to come later--is to merge the
two and stop storing hints in two different places.

mg.c
t/op/magic.t

diff --git a/mg.c b/mg.c
index 0ce58ab..b4c0692 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -2590,6 +2590,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
        break;
     case '\010':       /* ^H */
        PL_hints = SvIV(sv);
+       CopHINTS_set(&PL_compiling, PL_hints);
        break;
     case '\011':       /* ^I */ /* NOT \t in EBCDIC */
        Safefree(PL_inplace);
index 7abddbe..7a929d0 100644 (file)
@@ -5,7 +5,7 @@ BEGIN {
     chdir 't' if -d 't';
     @INC = '../lib';
     require './test.pl';
-    plan (tests => 179);
+    plan (tests => 180);
 }
 
 # Test that defined() returns true for magic variables created on the fly,
@@ -634,6 +634,18 @@ fresh_perl_is
  'select f; undef *f; ${q/|/}; print STDOUT qq|ok\n|', "ok\n", {},
  '[perl #115206] no crash when vivifying $| while *{+select}{IO} is undef';
 
+# ${^OPEN} and $^H interaction
+# Setting ${^OPEN} causes $^H to change, but setting $^H would only some-
+# times make ${^OPEN} change, depending on whether it was in the same BEGIN
+# block.  Don’t test actual values (subject to change); just test for
+# consistency.
+my @stuff;
+eval '
+    BEGIN { ${^OPEN} = "a\0b"; $^H = 0;          push @stuff, ${^OPEN} }
+    BEGIN { ${^OPEN} = "a\0b"; $^H = 0 } BEGIN { push @stuff, ${^OPEN} }
+1' or die $@;
+is $stuff[0], $stuff[1], '$^H modifies ${^OPEN} consistently';
+
 
 # ^^^^^^^^^ New tests go here ^^^^^^^^^