开发者

What does it mean to do "$var = *$self->{class_var};"

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜