7stud has asked for the wisdom of the Perl Monks concerning the following question:

#Define three x variables: $x = 10; @x = (1, 2); sub x { print "x\n"; } $val = *x{ARRAY}; print "@{$val}", "\n"; --output:-- 1 2 $what = *x; print $what, "\n"; --output:-- *main::x $val = $what{ARRAY}; print "@{$val}", "\n"; --output:-- (newline)

What does $fh = *NAME accomplish, and how can I use $fh?

Replies are listed 'Best First'.
Re: typeglob: $var = *x ???
by ikegami (Patriarch) on Jun 16, 2011 at 00:53 UTC

    What does $fh = *NAME accomplish

    It puts the symbol table entry for NAME, a type glob (aka glob aka GV), in $fh.

    and how can I use $fh?

    @{ *$var{ARRAY} }, or even @{ *$var } or @{ $var }.

    $ perl -E'@x=qw( a b c ); $var = *x; say for @{ *$var{ARRAY} }' a b c

    All three also work if $var = \*x;.

      Thanks. So, I have to dereference the variable I assigned the typeglob to in order to turn it back into a typeglob? For instance,

      $val = *x; print "@{ *{ $val } }";

      Based on the output here:

      print $val; --output:-- *main::x

      ...it's not obvious that $val needs dereferencing.

      All three also work if $var = \*x;.

      But I did $var = *x, which is not the same:

      $what = *x; print $what, "\n"; $what = \*x; print $what, "\n"; *main::x GLOB(0x10082ad88)

      It seems like in the first case, I wouldn't have to dereference $what into a typeglob, where I would expect to do so in the second case.

      Also, why can I do this:

      $fh = *STDOUT; print $fh 'hello', "\n"; --output:-- hello

      ...and not this:

      $STDOUT = 10; $fh = *STDOUT; print ($fh + 2); --output:-- 2

        But I did $var = *x

        So did I. I said \*x also works.

        it's not obvious that $val needs dereferencing.

        I showed that it doesn't need dereferencing.

        $gv = *x; @$gv => @x

        Of course, one needs to use the sigil to access the components of the glob.

        $gv = *x; $gv{ARRAY} # Obviously wrong. *$gv{ARRAY} # Ok

        ...and not this:

        Do you really want print($count + 2) to use $count as a file handle?

        print(STDOUT + 2) => print( { STDOUT } 2 )

        Barewords will be handled as expected, but anything else followed by what could be an infix operator will be treated as an argument to that operator.

        print(*STDOUT + 2) => print( { select() } *STDOUT+2 ) print(*$x + 2) => print( { select() } *$x+2 ) print($x + 2) => print( { select() } $x+2 )