Что означает "$ 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, немного в вопросе