I have tried to search for this, but have come up with nothing.
I am just curious as to why one would put the asterisk in the scenario below:
$var = *$self->{class_var};
What does the * do in t开发者_高级运维his situation?
Update
I took the above from the Net::Telnet module and I am simply trying to understand it.
The actual code is:
$s = *$self->{net_telnet};
I wonder, then, is net_telnet the package name?
%main::some_hash = (class_var => 'xyz');
my $self = *main::some_hash;
print *$self->{class_var}, "\n"; # prints 'xyz'
In short, this is an antiquated way of passing around a reference to a hash in the symbol table. The *
before $self
dereferences the value in $self
as a typeglob. The ->{class_var}
then dereferences that typeglob as a hash, and looks up the class_var
key.
Update:
Digging down through the class hierarchy reveals that the object is being created in IO::Handle
with:
sub new {
my $class = ref($_[0]) || $_[0] || "IO::Handle";
@_ == 1 or croak "usage: new $class";
my $io = gensym;
bless $io, $class;
}
Symbol::gensym
returns a complete typeglob, of which the IO
slot is mainly used. However, since it is a full typeglob, the sub-modules are exploiting that fact and storing their data in the various other glob fields, namely the HASH
portion.
From the short bit of code you have I'm assuming $self
holds a typeglob. You can access the sub elements explicitly as eugene y mentions, or implicitly by using any standard dereference syntax on the typeglob.
#!/usr/bin/perl
use strict;
use warnings;
our %test = ( class_var => "test class_var" );
our @test = qw(one four nine);
my $self = \*test;
print "Self is '$self'\n";
my $var1 = *{$self}{HASH}{class_var};
print "Var1 is '$var1'\n";
my $var2 = *$self->{class_var};
print "Var2 is '$var2'\n";
my $var3 = ${*{$self}}{class_var};
print "Var3 is '$var3'\n";
my $var4 = ${*$self}{class_var};
print "Var4 is '$var4'\n";
my $x_scale = *$self{ARRAY}[0];
print "x_scale is '$x_scale'\n";
my $y_scale = *$self->[1];
print "y_scale is '$y_scale'\n";
my $z_scale = ${*$self}[2];
print "z_scale is '$z_scale'\n";
Typeglob reference (outside of symbol aliasing) are most often used for the IO slot which allows an object to be used as a file handle, but since the typeglob holds one of each type of variable the other variable slots can be used to store additional state data.
The typeglob doesn't have to be global, Symbol::gensym
can create a typeglob that is basically anonymous.
This is quite probably dealing with a filehandle object. The filehandle itself is stored in the glob's fh slot, but metadata about the filehandle is stored in the glob's hash slot.
So this is saying
$var = *{$self}{class_var}
i.e. dereferencing $self as a typeglob, and then using it as a hash.
You can't do $self->{class_var} because it's not a HASH ref, it's a GLOB ref.
use strict;
my $fh;
my $self = \*fh;
*$self->{val} = 'foo';
I have used $fh
as an example thing, but in fact IO::Handle (probably) will use some other way of creating a glob ref. But with this snippet of code you should see that
print ref $self;
says GLOB
, but you can still
print *$self->{val};
to get foo
.
Further reading here: http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles
*$var
syntax gives you access to a set of global variables by name. For example, $foo
, @foo
, %foo
, and *foo
:
package main;
no strict;
$foo = 'bar'; # global variable!
@main::foo = qw(an array);
%foo = ('hash' => 'table');
open foo, '>', '/tmp/foo';
$self = 'foo';
print "\$$self is ${*$self}\n"; # $foo
print "\@$self is @{*$self}\n"; # @foo
print "\%$self is {",
(map {$_, " => ", *$self->{$_}, ","} keys %{*$self}),
"}\n";
print "Performing operations on the $self filehandle:\n";
print {*$self} "hello world\n";
close *$self;
open X, '<', '/tmp/foo';
print <X>;
close X;
$foo is bar @foo is an array %foo is {hash => table,} Performing operations on the foo filehandle: hello world
Of course, in these modern times with references and lexical variables, anything done with code like this could probably be done in a better way.
looks like a case of someone doing something with typeglobs; for example *$self could be a subclass implementing a file handle
@Dave Sherohman, take a look at IO::Pipe's source. it contains some funny code which play a lots with typeglobs, a bit in the question
精彩评论