The SVs_RMG
flag (which is what SvRMAGICAL
tests for and SvRMAGICAL_on/SvRMAGICAL_off
sets/clears) means that the variable has some magic associated with it other than a magic getter method (which is indicated by the SVs_GMG
flag) and magic setter method (indicated by SVs_SMG
).
I'm getting out of my depth, here, but examples of variables where RMAGIC
is on include most of the values in %ENV
(the ones that are set when the program begins, but not ones you define at run-time), the values in %!
and %SIG
, and stash values for named subroutines (i.e., in the program
package main;
sub foo { 42 }
$::{"foo"}
is RMAGICAL and $::{"bar"}
is not). Using Devel::Peek
is a little bit, but not totally enlightening about what this magic might be:
$ /usr/bin/perl -MDevel::Peek -e 'Dump $ENV{HOSTNAME}'
SV = PVMG(0x8003e910) at 0x800715f0
REFCNT = 1
FLAGS = (SMG,RMG,POK,pPOK)
IV = 0
NV = 0
PV = 0x80072790 "localhost"\0
CUR = 10
LEN = 12
MAGIC = 0x800727a0
MG_VIRTUAL = &PL_vtbl_envelem
MG_TYPE = PERL_MAGIC_envelem(e)
MG_LEN = 8
MG_PTR = 0x800727c0 "HOSTNAME"
Here we see that the scalar held in $ENV{HOSTNAME}
has an MG_TYPE
and MG_VIRTUAL
that give you the what, but not the how and why of this variable's magic. On a "regular" magical variable, these are usually (always?) PERL_MAGIC_sv
and &PL_vtbl_sv
:
$ /usr/bin/perl -MDevel::Peek -e 'Dump $='
SV = PVMG(0x8008e080) at 0x80071de8
REFCNT = 1
FLAGS = (GMG,SMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x80085aa8
MG_VIRTUAL = &PL_vtbl_sv
MG_TYPE = PERL_MAGIC_sv(\0)
MG_OBJ = 0x80071d58
MG_LEN = 1
MG_PTR = 0x80081ad0 "="
There is one place in the perl source where SvRMAGICAL_off
is used -- in perlio.c
, in the XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
.
XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
{
dXSARGS;
SV * const sv = SvRV(ST(1));
AV * const av = newAV();
MAGIC *mg;
int count = 0;
int i;
sv_magic(sv, MUTABLE_SV(av), PERL_MAGIC_ext, NULL, 0);
SvRMAGICAL_off(sv);
mg = mg_find(sv, PERL_MAGIC_ext);
mg->mg_virtual = &perlio_vtab;
mg_magical(sv);
Perl_warn(aTHX_ "attrib %" SVf, SVfARG(sv));
for (i = 2; i < items; i++) {
STRLEN len;
const char * const name = SvPV_const(ST(i), len);
SV * const layer = PerlIO_find_layer(aTHX_ name, len, 1);
if (layer) {
av_push(av, SvREFCNT_inc_simple_NN(layer));
}
else {
ST(count) = ST(i);
count++;
}
}
SvREFCNT_dec(av);
XSRETURN(count);
}
where for some reason (again, I'm out of my depth), they want that magic turned off during the mg_find
call.
mg_find
, then restores it by callingmg_magical
. The thing is, I don't thinkmg_find
cares about it at all. 2. The magic is employed to ensure the C data associated with the variable are freed. A more common (and most likely simpler) solution is to bless the variable into a class with a destructor. – Kerbstonesv_bless
:) To create a destructor, create a sub namedDESTROY
. – Kerbstone