2011-02-11 125 views
10

我试图寻找这个,但没有拿出任何东西。

我只是好奇,为什么一会就把星号在下面的场景:

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

什么是*在这种情况下怎么办?

更新

我把上述从网::远程登录模块,我只是试图去了解它。

实际的代码是:

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

我想知道的话,是net_telnet包的名称?

+1

我从来没有见过这个构造,但它看起来像是在用邪恶的东西和间接引用(即将变量的名称存储在另一个变量中)。 *不寒而栗* –

+0

'net_telnet'不是一个包名称,它是一些sockethandle元数据(对于由'* self'引用的句柄)存储在符号表中。 – mob

回答

6

从你有一小段代码我假设$self拥有一个typeglob。您可以像eugene y提及的那样显式地访问子元素,或者通过在typeglob上使用任何标准的dereference语法来隐式地访问这些子元素。 (外符号混叠)

#!/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"; 

类型团参考最常用于IO槽,其允许一个对象被用作文件句柄,但是由于类型团保持各类型的变量的其它可变时隙中的一个可以用来存储附加的状态数据。

typeglob不一定是全局的,Symbol::gensym可以创建一个基本上是匿名的typeglob。

2

看起来像某人用typeglobs做某事的情况;例如* $ self可能是一个实现文件句柄的子类
@Dave Sherohman,看看IO::Pipe的来源。它包含一些有趣的代码,其中有很多与typeglobs玩,有点在问题

3

这很可能是处理文件句柄对象。文件句柄本身存储在glob的fh插槽中,但关于文件句柄的元数据存储在glob的散列插槽中。

所以这是说

$var = *{$self}{class_var} 

即提领$自身作为一个类型团,然后用它作为哈希值。

你不能做$ self - > {class_var},因为它不是一个HASH ref,它是一个GLOB ref。

use strict; 

my $fh;  

my $self = \*fh; 

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

我已经使用$fh作为例子的事情,但实际上IO ::句柄(可能)会使用创造了水珠裁判的一些其他的方式。但是,在这个片段中的代码,你应该看到

print ref $self; 

GLOB,但你仍然可以

print *$self->{val}; 

得到foo

延伸阅读这里:http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles

3

*$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 

当然,在这些近代索引和词法变量,任何与代码就像这样很可能在完成更好的方法。

+0

这个答案是严格禁止的,这在代码中几乎肯定不是这种情况,但仍然是对整个glob概念的一个很好的概述:) – Altreus

+0

如果您限定所有全局变量名称,您仍然可以使用strict - '$ foo - > $ :: foo'或'$ main :: foo'。 – mob

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

my $self = *main::some_hash; 

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

简而言之,这是传递给符号表中的散列引用的过时的方式。在$self之前的*$self中的值解除引用作为类型球。 ->{class_var}然后将这个typeglob解引用为散列,并查找class_var密钥。

更新:

通过类层次结构向下挖掘揭示了在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返回完整类型团,其中主要用的IO槽。然而,由于它是一个完整的类型块,子模块正在利用这一事实并将它们的数据存储在各种其他glob字段中,即HASH部分。

+2

+1很好的解释。 Perldata也提到了这个问题:“这曾经是通过引用函数传递数组和哈希的首选方式,但现在我们有真正的参考,这很少需要。” –