develooper Front page | perl.perl5.porters | Postings from November 2016

ties and magic and saving state

Thread Next
From:
demerphq
Date:
November 14, 2016 20:32
Subject:
ties and magic and saving state
Message ID:
CANgJU+U+vZUu=U4wYS2iaWOTwakQkZcpJP5BNhUa3crkMyRngw@mail.gmail.com
Hey,

Sorry I mangled the discussion there about saving state and why @+ and
%+ are special as far as saving state.

My point in referring to @+ and @- and %+ and %- as all being "ties",
despite the fact that @+ and @- are implemented using magic proper,
and the later through a tie proper, is that they all expose state that
they do not themselves store. They "tie" their output to a secondary
data structure, through a code wrapper of some sort.

A regexp object contains a regexp_paren_pair *offs, which is used to
store the offsets of the beginning and end of the match, and the
beginning and end of each capture buffers that were used in the
pattern.

A regexp object also can contain an HV * which is used to map the
names of the named capture buffers to their numeric form. IOW, in
/(?<foo>foo)/ we have $1 and we have $+{foo}, and the HV* contains a
mapping of 'foo' to 1.

The dynamic scoping aspect of the regex vars is exposed via PL_curpm,
which IIRC is the PMOP which last successfully matched, and the PMOP
contains a pointer to the last matched REGEXP object. So you will see
patterns like this:

REGEXP *rx;
if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
...
}

With @+ and @- and @{^CAPTURE}, PERL_MAGIC_regdata/'D' magic is used
to call   Perl_magic_regdatum_get(), and  Perl_magic_regdata_get()
which are in mg.c. This type of magic behaves much like you might
expect from a tied array. In particular the @+ array, (for instance),
returns scalars which have PERL_MAGIC_regdatum/'d' magic and the index
they are for. Issuing a "get" on the 'd' magic'ed scalar then triggers
the Perl_magic_regdatum_get() which then returns the appropriate
index, or string.

With $1, $2, $3, etc, PERL_MAGIC_sv ('\0'/null magic?) is used to
"tie" the vars to  Perl_magic_get(), Perl_magic_set(),
Perl_magic_len(), which then use similar tricks to 'd' magic to link
through to the PL_curpm buffer in the regexp_paren_pair *offs
structure.

With %+ and %- PERL_MAGIC_tied/'P' and PERL_MAGIC_tiedelem/'p' magic
is used in a similar way to link the vars to the function mappings in
ext/Tie-Hash-NamedCapture/NamedCapture.xs. Of course because it is a
proper tie this is a bit more involved than the simpler "pure magic"
approach for @+ and @-.

Either way, the setup code is in gv.c, in S_gv_magicalize().

So, if you want to save state for any of these vars, then you need to
save the state of PL_curpm. As far as I know the only thing that is
really "special" is that Tie-Hash-NamedCapture is not by statically
link the library, whereas since the "tie" logic for @+ and friends
lives in mg.c, you already have it loaded with the core libraries.

I imagine you could do something like ""=~/(?:)/ just before you
freeze your process, and then just manually set PL_curpm to be a copy
of that pattern when you start up next time.

cheers,
Yves
-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About