Magic typeglob aliasing in Package::Stash::PP (Moose)

70 views Asked by At

I've been looking through Package::Stash::PP (the none PP version is used by Class::MOP::Package). I'm trying to understand how it works and stumbled upon this block inside sub add_symbol:

{
   # using glob aliasing instead of Symbol::gensym, because otherwise,
   # magic doesn't get applied properly.
   # see <[email protected]> on p5p
   local *__ANON__:: = $namespace;
   no strict 'refs';
   no warnings 'void';
   no warnings 'once';
   *{"__ANON__::$name"};
}

What is the effect of the block? It appears to not do anything since the anonymous typeglob assignment is local to the scope. I examined the symbol table and also used Devel::Peek::Dump(), but did not see the significance of the mentioned block of code.

I tried searching but had no success finding the mentioned ticket: <20120710063744.19360

1

There are 1 answers

0
Tim Potapov On

Thanks Dave for that link. Although I do not understand entirely the significance of that block of code, the example in Dave's link sheds light on the problem.

Here is a brief test case showing the difference in:

  1. An empty stash variable.
  2. A new stash created using Symbol::gensym().
  3. A new stash created using a typeglob alias.
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"