Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks.

In the following code:

use strict; use warnings; use v5.24; my $a = 25; my $ra = \*a;


I am attempting to dereference $ra an obtain the value 25. It appears as though the symbol table concept is proving elusive. Thanks.

Replies are listed 'Best First'.
Re: Dereferencing a reference to a typeglob?
by Athanasius (Archbishop) on Oct 29, 2016 at 03:50 UTC

    Lexical variables (those declared with my) are not stored in the symbol table. For that, you need a package global, and three two levels of dereferencing:

    13:45 >perl -Mstrict -wE "our $x = 25; my $rx = \*x; say $$rx;" *main::x 13:46 >perl -Mstrict -wE "our $x = 25; my $rx = \*x; say $$$rx;" 25 13:46 >

    This sounds like an XY Problem. What are you really trying to do?

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Dereferencing a reference to a typeglob?
by BrowserUk (Patriarch) on Oct 29, 2016 at 04:26 UTC

    As other have said, typeglobs are globals. If you're comfortable with that, then this will get you started on how to assign to, and dereference them:

    our *a = \25; *a = [1..10]; *a = { 'a'..'z' };; printf "Scalar:%s\nArray:[ %s ]\nHash:{ %s }\n", $a, join(',', @a ), j +oin('.', %a );; Scalar:25 Array:[ 1,2,3,4,5,6,7,8,9,10 ] Hash:{ w.x.e.f.a.b.m.n.s.t.y.z.u.v.c.d.k.l.q.r.g.h.i.j.o.p } printf "Scalar:%s\nArray:[ %s ]\nHash:{ %s }\n", ${*a}, join(',', @{*a +} ), join('.', %{*a} );; Scalar:25 Array:[ 1,2,3,4,5,6,7,8,9,10 ] Hash:{ w.x.e.f.a.b.m.n.s.t.y.z.u.v.c.d.k.l.q.r.g.h.i.j.o.p }

    Of course, that's only three of the six things that can live in a typeglob; but I'd have to look the others up as I've rarely used them.

    If you want the full skinny on them, see MJD's page on them.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Dereferencing a reference to a typeglob?
by AnomalousMonk (Archbishop) on Oct 29, 2016 at 04:09 UTC

    Further to what Athanasius posted: If you really want to use a lexical (i.e., my) variable, try:

    c:\@Work\Perl>perl -wMstrict -le "my $a = 25; my $ra = \$a; ;; print $ra; print $$ra; " SCALAR(0x432814) 25
    Please see perlref, perlreftut.


    Give a man a fish:  <%-{-{-{-<

Re: Dereferencing a reference to a typeglob?
by LanX (Saint) on Oct 29, 2016 at 08:59 UTC
    You are most likely confusing two technologies, please tell us what you try to achieve.

    Typeglobs are actually difficult to handle because they introduce more magic than normal references.

    Most Perl users probably never need them , since with lexical variables - i.e. declared with my - they are useless.

    Typeglobs are helpful to manipulate the symbol table, but this is already "meta" stuff.

    I think you just need to read perlref for how to handle references of lexicals.

    Please don't apply Perl4 documentation to Perl5, Perl4 didn't have lexicals, that's why typeglobs were used there for referencing / dereferencing of globals and "aliasing".

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      Hm. There are still plenty of places where references to typeglobs are relevant in Perl5:

      1. File handles: Even lexical file handles are references to an underlying typeglob:
        open my $fh, '>', 'fred.junk'; Dump( $fh );; SV = RV(0x3c728b0) at 0x3c728a0 REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0x3c72950 SV = PVGV(0x3c82d38) at 0x3c72950 REFCNT = 1 FLAGS = () NAME = "$fh" NAMELEN = 3 GvSTASH = 0x36bde0 "main" GP = 0x3c93298 SV = 0x0 REFCNT = 1 IO = 0x3c72168 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x0 CVGEN = 0x0 LINE = 1 FILE = "(eval 18)" FLAGS = 0x0 EGV = 0x3c72950 "$fh"
      2. Directory handles: Even lexical ones:
        opendir my $dir, '.'; Dump( $dir );; SV = RV(0x2762e8) at 0x2762d8 REFCNT = 1 FLAGS = (PADMY,ROK) RV = 0x3c721e0 SV = PVGV(0x3c82d38) at 0x3c721e0 REFCNT = 1 FLAGS = () NAME = "$dir" NAMELEN = 4 GvSTASH = 0x36bde0 "main" GP = 0x3c93298 SV = 0x0 REFCNT = 1 IO = 0x3c72198 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x0 CVGEN = 0x0 LINE = 1 FILE = "(eval 22)" FLAGS = 0x0 EGV = 0x3c721e0 "$dir"
      3. Coderefs: Every time you call, or cause to be called, a subroutine indirectly:
        sub cmp { $_[0] <=> $_[1] };; Dump( \&cmp );; SV = RV(0x2762e8) at 0x2762d8 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x3c72858 SV = PVCV(0x3c5a028) at 0x3c72858 REFCNT = 2 FLAGS = () COMP_STASH = 0x36bde0 "main" START = 0x3d0ef48 ===> 0 ROOT = 0x3d0eed0 GVGV::GV = 0x3c721f8 "main" :: "cmp" FILE = "(eval 9)" DEPTH = 0 FLAGS = 0x0 OUTSIDE_SEQ = 1935 PADLIST = 0x3c72840 PADNAME = 0x3c72828(0x3cf7358) PAD = 0x3c72210(0x3cf7618) OUTSIDE = 0x36beb8 (UNIQUE)

      Being dismissive of these more obscure but still totally current and relevant areas of Perl because you rarely interact with them directly or don't understand them is of no help to anyone.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Thanks for proving my point.

        All of this can be handled without manipulating the symbol table or using the *star operator.

        Showing advanced techniques like *a=\&func where a function ref is mapped to a special "slot" of a very unique data structure called "typeglob" residing in the symbol table is contra productive for a beginner.

        Especially if he just wants to learn dereferencing of lexicals.

        It's enough hinting that there are use cases in meta programming Perl.

        > because you rarely interact with them directly or don't understand them is of no help to anyone.

        Thanks again for the provocation.

        But I'm not going to play and you already know my opinion about you.

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

        UPDATE

        deleted honorary title ...

Re: Dereferencing a reference to a typeglob? [Postfix Dereference Syntax]
by kcott (Archbishop) on Oct 29, 2016 at 11:59 UTC
    "...use v5.24;..."

    "Dereferencing a reference to a typeglob" can be done with Postfix Dereference Syntax (i.e. $globref->**). Some examples:

    $ perl -v | head -2 | tail -1 This is perl 5, version 24, subversion 0 (v5.24.0) built for darwin-th +read-multi-2level $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -E' $ perle 'use 5.024; my $x = \*STDERR; say "OUT"; say { $x->** } "ERR"' OUT ERR $ perle 'use 5.024; my $x = \*STDERR; say "OUT"; say { $x->** } "ERR"' + > /dev/null ERR $ perle 'use 5.024; my $x = \*STDERR; say "OUT"; say { $x->** } "ERR"' + 2> /dev/null OUT $

    I wrote a fair amount about using this syntax in general, just yesterday: "Re^3: Syntax Question Related to "join" on a Complex Data Structure [postderef and postderef_qq]". You'll find examples of "$arrayref->@*", which may be closer (than "$globref->**") to the type of thing you're after.

    — Ken

      ++, but this doesn't solve the OP's problem of derefing a lexical, it acts the same way as a normal deref does (unless I'm missing something):

      perl -E 'my $a=25; my $x=\*a; say $x->**; say $$x;' *main::a *main::a
        > perl -E 'my $a=25; my $x=\*a; ... '

        This code doesn't do what you think it does.

        *a is always addressing the typeglob of the global symbol(s) named a , i.e. &a, $a, @a, %a the filehandle a and the format a .

        ( see here for how to use the clearer {SLOT} syntax.)

        Maybe this code example makes it clearer:

        DB<104> $a=42; my $a=666; my $ra=\*a; print $$$ra 42

        update

        Best think of the STASH (= Symbol Table Hash) as a Hash of Hashes, where the second level "hash" is a special structure called "glob" which always has exactly 6 fixed entries, which are either undef or a reference.

        Lexicals use a totally different mechanism in the so called "Pad" and can't be addressed with * because there is nothing like a "lexical glob" unifying all lexical symbols.

        If you use PadWalker to introspect pads you'll see that $x', '%x', '@x listed as separate top level symbols.

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

Re: Dereferencing a reference to a typeglob? [Postfix Dereference Chaining]
by kcott (Archbishop) on Oct 30, 2016 at 00:32 UTC

    Using the postfix syntax, you can chain the operations to first dereference the globref, then the scalarref:

    $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -E' $ perle 'our $a = 25; my $ra = \*a; say $ra->*{SCALAR}->$*' 25

    Perl has a number of special variables[perlvar]: $a is one of them (used mainly when sorting); *a is its typeglob.

    $ perle '1 for sort { say +(\*a)->*{PACKAGE}; say +(\*a)->*{SCALAR}->$ +*; say $a } 1 .. 3' main 1 1 main 2 2

    There's also a $b. Everything that applies to $a; also applies to $b.

    — Ken

Re: Dereferencing a reference to a typeglob?
by AnomalousMonk (Archbishop) on Oct 29, 2016 at 06:12 UTC

    Just as a matter of (perhaps rather idle) curiosity, where do all the  &#9474; (box drawing light vertical?) entities in the OP (if they have not already been cleaned up) come from?


    Give a man a fish:  <%-{-{-{-<

      I assume the OP pasted that character into the text entry box, and then the combination of Perlmonks input sanitation and code tags turn them into literal HTML escapes.