Magic typeglob混叠在Package::Stash::PP(驼鹿)



我一直在看Package::Stash::PP(无PP版本由class::MOP::Package使用)。我试图了解它是如何工作的,偶然发现了sub add_symbol内的这个块:

{
# using glob aliasing instead of Symbol::gensym, because otherwise,
# magic doesn't get applied properly.
# see <20120710063744.19360.qmail@lists-nntp.develooper.com> on p5p
local *__ANON__:: = $namespace;
no strict 'refs';
no warnings 'void';
no warnings 'once';
*{"__ANON__::$name"};
}

阻塞的效果是什么?它似乎没有做任何事情,因为匿名typeglob赋值是局部作用域。我检查了符号表,也使用了Devel::Peek::Dump(),但是没有看到提到的代码块的重要性。

我试着搜索,但没有成功找到提到的票:<20120710063744.19360

感谢Dave提供的链接。虽然我不能完全理解这段代码的意义,但是Dave的链接中的例子说明了这个问题。

下面是一个简短的测试用例,显示了

的区别:
  1. 一个空的存储变量。
  2. 使用Symbol::gensym()创建新的存储库。
  3. 使用typeglob别名创建新的存储库。
perl -MDevel::Peek -MSymbol -e '
Dump $class::{var}; # 1. Empty stash
Dump gensym;         # 2. New stash, but with wrong name.
{
local *__ANON__:: = %class::;
*{"__ANON__::var"};
}
Dump $class::{var};   # 3. New stash with correct name.
'
# Output:
# 1. Null since no stash (or empty).
SV = NULL(0x0) at 0x7304ffe240
REFCNT = 2147483632
FLAGS = (READONLY,PROTECT)
# 2. New stash, but the name in GvSTASH is wrong.
SV = IV(0x730420b7e8) at 0x730420b7f8
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x730420b648
SV = PVGV(0x730435c120) at 0x730420b648
REFCNT = 1
FLAGS = ()
NAME = "GEN0"
NAMELEN = 4
GvSTASH = 0x73042f46d8      "Symbol"
FLAGS = 0x0
GP = 0x730424c640
SV = 0x0
REFCNT = 1
IO = 0x0
FORM = 0x0
AV = 0x0
HV = 0x0
CV = 0x0
CVGEN = 0x0
GPFLAGS = 0x0 ()
LINE = 104
FILE = "/data/data/com.termux/files/usr/lib/perl5/5.34.0/Symbol.pm"
EGV = 0x730420b648        "GEN0"
# 3. New stash with the correct name due to this aliasing trick.
SV = PVGV(0x730435c120) at 0x730420b7f8
REFCNT = 1
FLAGS = (MULTI)
NAME = "var"
NAMELEN = 3
GvSTASH = 0x73042f45d0        "class"
FLAGS = 0x2
GP = 0x730432bd70
SV = 0x0
REFCNT = 1
IO = 0x0
FORM = 0x0
AV = 0x0
HV = 0x0
CV = 0x0
CVGEN = 0x0
GPFLAGS = 0x0 ()
LINE = 1
FILE = "-e"
EGV = 0x730420b7f8  "var"

最新更新