Open p5pRT opened 10 years ago
Generally\, a value assigned to an element of a tied hash gets passed through to the tied STORE method\, so any kind of scalar can be handled by a tied hash\, just as an ordinary hash can contain any kind of scalar. But it doesn't work for regexp scalars. Here's what one looks like in an ordinary hash:
$ perl -MDevel::Peek -lwe '$a{x} = ${qr/foo/}; Dump $a{x}' SV = REGEXP(0x14aa9a0) at 0x147ba68 REFCNT = 1 FLAGS = (POK\,FAKE\,pPOK) PV = 0x1490460 "(?^:foo)" CUR = 8 LEN = 0 EXTFLAGS = 0x680000 (CHECK_ALL\,USE_INTUIT_NOML\,USE_INTUIT_ML) INTFLAGS = 0x0 NPARENS = 0 LASTPAREN = 0 LASTCLOSEPAREN = 0 MINLEN = 3 MINLENRET = 3 GOFS = 0 PRE_PREFIX = 4 SEEN_EVALS = 0 SUBLEN = 0 SUBBEG = 0x0 ENGINE = 0x2b04257e50e0 MOTHER_RE = 0x1496c28 PAREN_NAMES = 0x0 SUBSTRS = 0x149a980 PPRIVATE = 0x149ee90 OFFS = 0x1490840
And here's what happens with a tied hash:
$ perl -lwe '{ package Foo; use Devel::Peek; sub TIEHASH { bless({}\, $_[0]) } sub STORE { Dump $_[2] } } my %a; tie %a\, "Foo"; $a{x} = ${qr/foo/}' SV = PVLV(0xe8ae40) at 0xe7d560 REFCNT = 2 FLAGS = (POK\,pPOK) IV = 0 NV = 0 PV = 0xe8e980 "(?^:foo)"\0 CUR = 8 LEN = 16 MAGIC = 0xe8ed20 MG_VIRTUAL = &PL_vtbl_packelem MG_TYPE = PERL_MAGIC_tiedelem(p) MG_FLAGS = 0x02 REFCOUNTED MG_OBJ = 0xe7cd38 SV = IV(0xe7cd28) at 0xe7cd38 REFCNT = 2 FLAGS = (ROK) RV = 0xe61c18 SV = PVHV(0xe66890) at 0xe61c18 REFCNT = 1 FLAGS = (OBJECT\,SHAREKEYS) STASH = 0xe7d5d8 "Foo" ARRAY = 0x0 KEYS = 0 FILL = 0 MAX = 7 RITER = -1 EITER = 0x0 MG_LEN = -2 MG_PTR = 0xe7cea0 => HEf_SVKEY SV = PV(0xe5fd90) at 0xe7cea0 REFCNT = 2 FLAGS = (POK\,pPOK) PV = 0xe87b60 "x"\0 CUR = 1 LEN = 16 TYPE = T TARGOFF = 0 TARGLEN = 0 TARG = 0xe731e8 FLAGS = 0
Note that the value in the scalar received by the STORE method is a plain string\, the stringification of the regexp. The basic problem seems to be a collision between the use of the SvTYPE field to denote a special type of scalar value\, SVt_REGEXP\, and the the use of the same field to denote a special type of scalar container\, SVt_PVLV. Although they're horribly interleaved\, the container and value aspects of scalars are for the most part orthogonal. The failure of orthogonality here is jarring.
This program may more clearly demonstrate the problem for other readers:
use 5.19.9; use Tie::Hash;
my $qr = qr/foo/; say ref \${ $qr };
{ my %h; $h{qr} = $$qr; say ref \$h{qr}; }
{ tie my %h\, 'Tie::StdHash'; $h{qr} = $$qr; say ref \$h{qr}; }
-- rjbs
The RT System itself - Status changed from 'new' to 'open'
Migrated from rt.perl.org#121477 (status was 'open')
Searchable as RT121477$