Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

perl

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 this 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?

like image 753
Trenton Avatar asked Feb 11 '11 15:02

Trenton


2 Answers

%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.

like image 128
Eric Strom Avatar answered Sep 18 '22 00:09

Eric Strom


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.

like image 32
Ven'Tatsu Avatar answered Sep 20 '22 00:09

Ven'Tatsu