Что означает "$ var = * $self → {class_var};"

Я попытался найти это, но ничего не придумал.

Мне просто интересно, почему бы поставить звездочку в сценарий ниже:

$var = *$self->{class_var};

Что делает * в этой ситуации?

Обновление

Я взял это из модуля Net:: Telnet, и я просто пытаюсь понять его.

Фактический код:

$s = *$self->{net_telnet};

Интересно, значит, net_telnet имя пакета?

Ответ 1

Из короткого бита кода, который у вас есть, я предполагаю, что $self содержит типglob. Вы можете получить доступ к подэлементам явно как eugene y, или неявно, используя любой стандартный синтаксис разыменования в 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 (вне псевдонимов символов) чаще всего используется для слота ввода-вывода, который позволяет использовать объект в качестве дескриптора файла, но поскольку типglob содержит один из переменных каждого типа, остальные слоты переменной могут использоваться для хранить дополнительные данные состояния.

Типglob не должен быть глобальным, Symbol::gensym может создать типglob, который в основном анонимный.

Ответ 2

%main::some_hash = (class_var => 'xyz');

my $self = *main::some_hash;

print *$self->{class_var}, "\n";   # prints 'xyz'

Короче говоря, это устаревший способ передачи ссылки на хэш в таблице символов. * до $self разделяет значение в $self как типglob. ->{class_var} затем разыгрывает typeglob как хэш и ищет ключ class_var.

Update:

Выкалывание по иерархии классов показывает, что объект создается в IO::Handle с помощью:

sub new {
    my $class = ref($_[0]) || $_[0] || "IO::Handle";
    @_ == 1 or croak "usage: new $class";
    my $io = gensym;
    bless $io, $class;
}

Symbol::gensym возвращает полный типglob, из которого в основном используется слот IO. Однако, поскольку это полный типglob, подмодули используют этот факт и сохраняют свои данные в разных других полях glob, а именно в части HASH.

Ответ 3

Вероятно, это относится к объекту filehandle. Сам дескриптор файла хранится в слоте glob fh, но метаданные о дескрипторе файла хранятся в слоте хеш-памяти.

Итак, это говорит

$var = *{$self}{class_var}

то есть. разыгрывая $self как typeglob, а затем используя его как хэш.

Вы не можете сделать $self → {class_var}, потому что это не ссылка HASH, это ссылка GLOB.

use strict;

my $fh;    

my $self = \*fh;

*$self->{val} = 'foo';

Я использовал $fh как пример, но на самом деле IO:: Handle (возможно) будет использовать другой способ создания glob ref. Но с этим фрагментом кода вы должны увидеть, что

print ref $self;

говорит GLOB, но вы все еще можете

print *$self->{val};

чтобы получить foo.

Далее читайте здесь: http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles

Ответ 4

Синтаксис

*$var дает вам доступ к набору глобальных переменных по имени. Например, $foo, @foo, %foo и *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

Конечно, в эти современные времена со ссылками и лексическими переменными все, что было сделано с таким кодом, возможно, было бы лучше сделано.

Ответ 5

выглядит как случай, когда кто-то делает что-то с typeglobs; например, * $self может быть подклассом, реализующим дескриптор файла @Dave Sherohman, посмотрите IO:: Pipe. он содержит какой-то забавный код, который играет партии с typeglobs, немного в вопросе