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)
commit1c75beb82e2bc71836b8b226cb4e976792d1967c
treeabb0787518fa956de23734503525ef4d1a1868c5
parentae7a8a78f1dbd467b63525c5201b8377dc705e7b
Modifying ${^OPEN} changes the value of $^H:

$ ./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