SVs_RMG
标志(用于SvRMAGICAL
测试和设置/清除的内容SvRMAGICAL_on/SvRMAGICAL_off
)意味着该变量具有与它相关的一些魔法,而不是魔法 getter 方法(由SVs_GMG
标志指示)和魔法 setter 方法(由 指示SVs_SMG
)。
在这里,我已经超出了我的深度,但是RMAGIC
打开的变量示例包括大多数值%ENV
(程序开始时设置的值,但不是您在运行时定义的值),%!
和%SIG
, 和命名子程序的存储值(即,在程序中
package main;
sub foo { 42 }
$::{"foo"}
是 RMAGICAL 而$::{"bar"}
不是)。使用Devel::Peek
有点,但对这种魔法可能是什么并不完全有启发性:
$ /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"
在这里,我们看到保存的标量$ENV{HOSTNAME}
有一个MG_TYPE
和MG_VIRTUAL
,它给你什么,但不是这个变量的魔法的方式和原因。在“常规”魔法变量上,这些通常是(总是?)PERL_MAGIC_sv
和&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 "="
在 perl 源代码中有一个地方SvRMAGICAL_off
使用了 -perlio.c
在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);
}
mg_find
出于某种原因(再次,我超出了我的深度),他们希望在通话期间关闭魔法。