in reply to Re^3: symbol/glob hash explanation
in thread symbol/glob hash explanation

I did try that and it does not work, at least not on my 5.10.1

DB<2> $s = Symbol::gensym DB<3> x ${*$s}{goo} = 'ber' 0 'ber' * DB<4> x \%{*$s}{goo} syntax error at (eval 8)[/usr/share/perl/5.10/perl5db.pl:638] line 2, +near "}{goo" * DB<5> x \%{*$s} 0 HASH(0x86285e8) 'goo' => 'ber' * DB<6> x \%{*Symbol::GEN0} 0 HASH(0x87144e0) empty hash * DB<7> x ${*Symbol::GEN0}{goo} 0 undef DB<8> x $] 0 5.010001 DB<9> x $s 0 GLOB(0x86285b8) -> *Symbol::GEN0

...

* DB<8> x \%{*Symbol::GEN0} 0 HASH(0x8aab260) empty hash * DB<9> x \%{*{Symbol::GEN0}} 0 HASH(0x8aab260) empty hash * DB<10> x \%{*{*Symbol::GEN0}} 0 HASH(0x8aab260) empty hash * DB<11> x \%{'' . *$s} 0 HASH(0x8aab260) empty hash * DB<12> x \%{*$s} 0 HASH(0x8a5b5e8) 'goo' => 'ber' * DB<13> use Scalar::Util qw(refaddr) DB<14> x \%{*refaddr($s)} syntax error at (eval 20)[/usr/share/perl/5.10/perl5db.pl:638] line 2, + near "*refaddr(" * DB<15> x \%{refaddr($s)} 0 HASH(0x8b6eea0) empty hash * DB<16> x \%{sprintf "%x", refaddr($s)} 0 HASH(0x8b73ef0) empty hash * DB<17> x \%{*{"$s"}} 0 HASH(0x8b73c10) empty hash

It does not show up when I dump \%:: (or \%Symbol or \%Symbol:: or \%Symbol::GEN0 or \%Symbol::GEN0:: either (excluded for brevity) at least not that i can see.

Replies are listed 'Best First'.
Re^5: symbol/glob hash explanation
by BrowserUk (Patriarch) on May 03, 2011 at 15:21 UTC

    Looking into Symbol, that is apparently deliberate:

    my $genpkg = "Symbol::"; my $genseq = 0; sub gensym () { my $name = "GEN" . $genseq++; ## Instantiate the glob and take a reference to it. my $ref = \*{$genpkg . $name}; ## Delete the name, leaving a reference to an anonymous glob delete $$genpkg{$name}; ## return the ref $ref; }

    Thus, it effectively mirrors the behaviour [] and {} in that you have a reference to a structure that doesn't (no longer) appears in the pad (symbol table).

    The few times I've wanted an anonymous glob I've used:

    $r = do{ \local *FRED };; print $r;; GLOB(0x4055f70)

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Aha! Thank you!

      I definitely should have looked at Symbol.pm before using it in my examples... Now I see why they suggest that you use it (and why the IO modules use it).

      So taking into account that Symbol::gensym uses deliberate voodoo, going back to the STDIN example makes it more clear... It is in fact part of the *foo{THING} syntax (*foo{HASH} in these examples):

      DB<13> ${*STDIN}{goo} = 'ber' DB<14> x \%{*STDIN} 0 HASH(0x9a7d878) 'goo' => 'ber' * DB<15> x \%STDIN 0 HASH(0x9a7d878) 'goo' => 'ber' * DB<17> x *STDIN 0 *main::STDIN * DB<18> x *STDIN{HASH} 0 HASH(0x9a7d878) 'goo' => 'ber' * DB<19> x *STDIN{IO} 0 IO::Handle=IO(0x97a5980)

      And a full example demonstrating gensym's symbol table manipulation:

      * DB<6> $s = \*Symbol::GEN1 DB<7> x $s 0 GLOB(0x9cca740) -> *Symbol::GEN1 DB<8> x ${*$s}{goo} = 'ber' 0 'ber' * DB<9> x \%{*$s} 0 HASH(0x9d4ace8) 'goo' => 'ber' * DB<10> x \%Symbol::GEN1 0 HASH(0x9d4ace8) 'goo' => 'ber' * DB<13> x *Symbol::GEN1{HASH} 0 HASH(0x9d4ace8) 'goo' => 'ber' * DB<15> x *Symbol::GEN1{HASH}{pea} = 'nut' 0 'nut' DB<16> x \%{*$s} 0 HASH(0x9d4ace8) 'goo' => 'ber' 'pea' => 'nut' * DB<17> delete $Symbol::{GEN1} DB<18> x \%{*$s} 0 HASH(0x9d4ace8) 'goo' => 'ber' 'pea' => 'nut' * DB<19> x *Symbol::GEN1{HASH} 0 undef DB<20> x \%{*$s} 0 HASH(0x9d4ace8) 'goo' => 'ber' 'pea' => 'nut'

      So while there's definitely some black magic happening there (and with the symbol tables in general) I have a better idea of what is happening behind the curtain in this particular instance... I now see where that hash is going (or where it has been (or something like that)). Thank you very much!