首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Package::Stash::PP (Moose)中的魔术typeglob别名

Package::Stash::PP (Moose)中的魔术typeglob别名
EN

Stack Overflow用户
提问于 2021-10-21 20:35:41
回答 1查看 61关注 0票数 1

我一直在查找Package::Stash::PP (Class::MOP::Package使用的是none PP版本)。我试图理解它是如何工作的,并偶然发现了sub add_symbol中的这个块

代码语言:javascript
复制
{
   # 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

EN

回答 1

Stack Overflow用户

发布于 2021-10-22 16:19:39

谢谢Dave的链接。虽然我不能完全理解这段代码的意义,但Dave链接中的示例揭示了这个问题。

下面是一个简短的测试用例,展示了以下方面的差异:

typeglob

  • 为空的存储变量。

  • 使用typeglob别名创建的新存储创建的新存储。

代码语言:javascript
复制
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"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69668471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档