Jens Rehsack via RT wrote:
Show quoted text>I'd like to understand from a documentation - not by studying the perl core:
If you go strictly by the API documentation, then GvSV() isn't documented
as an lvalue. By assigning to it at all you're going beyond the public
API, and if you're doing that you have to be willing to use the core's
standards of documentation. But by all means open core tickets about
these issues: about whether lvalue GvSV() should be in the public API,
and about underdocumented API elements.
Show quoted text>a) What's the difference between SAVESPTR(GvSV()) and SAVEGENERICSV()?
There are two orthogonal differences here. The difference between
SAVESPTR() and SAVEGENERICSV() is in refcounting. SAVESPTR() is for
uncounted refs and SAVEGENERICSV() for counted refs. Details below on
(c) and (d). The difference between SAVE*(GvSV()) and SAVE*() is that
the localisation is being applied to a different thing. PL_firstgv is a
variable that holds a reference to a glob; GvSV(PL_firstgv) is the slot
within that glob that holds a reference to a scalar.
Show quoted text>b) Why does PL_firstg/PL_secondgv need to be saved twice while PL_defgv doesn't?
I think by "saved twice" you're referring to the saving of both
PL_firstgv and GvSV(PL_firstgv). These are saving two distinct things.
It is necessary to save, that is, to localise, whichever global things
one is going to write to. It's necessary to save PL_firstgv because
it then gets assigned to, and it's necessary to save GvSV(PL_firstgv)
because that gets assigned to as well. It's also necessary to save
GvSV(PL_defgv) because it'll be assigned to, but it is not necessary to
save PL_defgv because it's not assigned to. See also (e) below.
(Everything said for PL_firstgv also goes for PL_secondgv.)
Show quoted text>c) What does SAVESPTR() do?
SAVESPTR() saves a pointer value without touching refcounts, and so is
suitable for use on a variable that holds an uncounted reference, or
in some specific situations where everything that happens to a counted
reference is known. It saves the current value of the argument variable,
and upon unwinding the variable will be rewritten to contain the saved
value.
Show quoted text>d) What does SAVEGENERICSV() do?
SAVEGENERICSV() is for use on a variable that holds a counted reference,
and unfortunately its calling convention is a bit wonky. SAVEGENERICSV()
not only saves the old scalar pointer value but also creates and holds a
new counted reference to that scalar. The caller of SAVEGENERICSV() must
then immediately write the correct scalar pointer into the variable (if
it is not already correct) and increment its refcount. Upon unwinding,
whatever scalar is then referenced by the variable has its refcount
decremented, the old scalar pointer is written into the variable, and
its refcount is also decremented.
Show quoted text>e) Why does PL_firstg/PL_secondgv need a new muteable GV in opposite to PL_defgv?
It's not necessary to write to PL_defgv because it is reliably initialised
to refer to *_. There's only one *_ that matters, because code like
"$_" refers to the one in the main package regardless of the locally
selected package. PL_defgv is kept permanently pointing at the main *_
for everything to use.
On the other hand, it's necessary to write to PL_firstgv because it would
not otherwise be reliably set to refer to *a. It's only set locally
for a specific operation. Unlike *_, each package has its own *a,
and code like "$a" refers to the one in the locally selected package.
Things such as pp_sort and pairwise() have to look up the specific *a
that the caller will be using.
However, you could avoid having to save PL_firstgv by not using PL_firstgv
at all. It's not necessary for you to put your *a reference into a
global variable. You could put it in a variable that's internal to
your code, though you would then have to handle passing your internal
variable around yourself.
(Everything said for PL_firstgv/*a also goes for PL_secondgv/*b.)
Show quoted text>f) Why is the gv_fetchpvs/SAVESPTR/SAVEGENERICSV/... missing in perlapi?
gv_fetchpvs() has just not been documented, which looks like an oversight.
The SAVE*() macros are all undocumented, and it looks like they're
not intended to be public API. Their function forms, save_sptr(),
save_generic_svref(), et al, are listed as public API but are equally
undocumented. It's not clear whether they're really intended as
public API.
Regrettably, a lot of the older parts of the API are undocumented in
that manner. We're better at documenting new API functions, and we
do gradually fix the old ones when the occasion arises. Please do
open core tickets about missing API documentation that affects you,
to provide the occasion.
-zefram