1

我一直在查看Package::Stash::PPClass::MOP::Package使用无 PP 版本)。我试图了解它是如何工作的,并在里面偶然发现了这个块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

4

1 回答 1

1

感谢戴夫的链接。尽管我不完全理解该代码块的重要性,但 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"
于 2021-10-22T16:19:39.120 回答