2011-02-11 59 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也提到了這個問題:「這曾經是通過引用函數傳遞數組和哈希的首選方式,但現在我們有真正的參考,這很少需要。」 –