$ref = \%hash;
$ref = \@hash;
How do I do the same thing as reference using typeglob in perl?
What's the exact steps perl takes to interpret $$ref{key}?
On
I don't think you can do the exact same thing with typeglobs as you can do with references (for example lexical variables never involve a type glob). What do you want to achieve in the end?
As for $$ref{key}, perl proceeds as follows:
{...} indicates that $ref must be a hash reference
On
Perl is remarkably and famously experimental:
Try:
perl -MO=Terse -e' $ref = \%hash; $ret = $$ref{key}'
or:
perl -MO=Debug -e' $ref = \%hash; $ret = $$ref{key}'
and all will be revealed. If you have a debugging Perl, you can even do:
perl -Dt -e'$ref = \%hash; $ret = $$ref{key}'
On
Use the *foo{THING} syntax, which is documented in the Making References section of the perlref documentation.
A reference can be created by using a special syntax, lovingly known as the
*foo{THING}syntax.*foo{THING}returns a reference to the THING slot in*foo(which is the symbol table entry which holds everything known asfoo).$scalarref = *foo{SCALAR}; $arrayref = *ARGV{ARRAY}; $hashref = *ENV{HASH}; $coderef = *handler{CODE}; $ioref = *STDIN{IO}; $globref = *foo{GLOB}; $formatref = *foo{FORMAT};
For example:
#! /usr/bin/env perl
use strict;
use warnings;
our %hash = (Ralph => "Kramden", Ed => "Norton");
our @hash = qw/ apple orange banana cherry kiwi /;
my $ref;
$ref = *hash{HASH};
print $ref->{Ed}, "\n";
$ref = *hash{ARRAY};
print $ref->[1], "\n";
Output:
Norton orange
As for the second part of your question, adding
print $$ref{Ralph}, "\n";
after Ed produces the expected output. The compiler generates code for this line that goes through the following sequence:
$ref.$ref's thingie.But don't take my word for it. To cut down the volume of output, consider a similar two-liner:
my $ref = { Ralph => "Kramden" };
print $$ref{Ralph};
Running it with a perl compiled for debugging gets us
$ debugperl -Dtls ref
[...]
(ref:1) nextstate
=>
(ref:2) pushmark
=> *
(ref:2) padsv($ref) # STEP 1
=> * \HV()
(ref:2) rv2hv # STEP 2
=> * HV()
(ref:2) const(PV("Ralph"\0)) # STEP 3a
=> * HV() PV("Ralph"\0)
(ref:2) helem # STEP 3b
=> * PV("Kramden"\0)
(ref:2) print
=> SV_YES
(ref:2) leave
[...]
Note that it's slightly different for globals.
I'm not sure what your larger intent is, but there are some important caveats. Note that a typeglob represents a symbol table entry, so you can't get at lexicals this way because they live in pads, not the symbol table. For example, say you insert my @hash = ("splat"); just before the assignments to $ref in the code above. The result may surprise you.
$ ./prog "my" variable @hash masks earlier declaration in same scope at ./prog line 11. Norton orange
The behavior with respect to scalars may also be surprising.
*foo{THING}returnsundefif that particular THING hasn't been used yet, except in the case of scalars.*foo{SCALAR}returns a reference to an anonymous scalar if$foohasn't been used yet. This might change in a future release.
Tell us what you're trying to do, and we'll be able to give you specific, useful suggestions.
If you're asking how you get a reference to a type glob, it's just:
For a "literal name" of the symbol, (that is where you type in the exact name of the symbol), and not a variable. But, you can do this:
for a variable symbol. However, the above works with
strictand the easier one below doesn't:One of the nice things about
Symbol::qualify*, is that it handles package names as the second variable. So...does the same thing as
\*{$some_other_package.'::'.$symbol_name}and it works withstrict.Once you have the symbol ref, to get the slot, you have to deference the reference, so perl does not think you're trying to use it as a hash, like so.
Another Take
I put your two ideas together in a different way. If you have a symbol table reference, you can get the
HASHslot and that is a reference just like any other reference to a hash. So you can do the following.Either
Or
will work. These are safer, though
If you want to do this not with a direct entry, but a reference into the table, you would do the following:
NOTE:
%hashabsolutely needs to be a package variable. Only package variables reside in the symbol table (so only subs and@ISAand Exporter variables tend to be in modern symbol tables). Lexical variables (those declaredmy) reside in the "pad".UPDATE:
I have gotten away from using
Symbolso much. Curiously, even though it is core, it seems non-standard in the way Perlers do--and see--things. Instead, I use the direct way in what I call "no-blocks", as localized as I can make them.OR
I almost always use the
*STDERR{IO}idiom for a glob file handle reference. In modern Perl, these are usually objects.