本文假設(shè)你對(duì)Perl引用已經(jīng)有所了解。
關(guān)于Perl glob,筆者建議閱讀《Advanced Perl Programming》第一版的第三章和第二版的第一章。本文是筆者經(jīng)過(guò)閱讀以上內(nèi)容并經(jīng)過(guò)一些實(shí)踐后完成的。
我們都知道Perl的引用類似C語(yǔ)言的指針。
C指針:
int a = 1;
int* pa;
pa = &a;
引用都可以簡(jiǎn)單地看成是存儲(chǔ)了變量的地址:
在各種語(yǔ)言里,都有符號(hào)表(Symbol Table)的概念。符號(hào)表存儲(chǔ)著各種作用域里的符號(hào)(Symbol)。這里說(shuō)的Symbol是指我們編程時(shí)用到的各種名稱,包括變量名、函數(shù)名等。比如上面的“a”、“pa”、“ra”等都是symbol??聪旅娴拇a:
my $a = "sdd";
my $b = 34;
my @b = (2,3);
my %b = (name => 'me', age => 28);
sub b {
print "hello\n";
}
產(chǎn)生的符號(hào)表:
... |
... |
symbol a |
變量$a的地址 |
... |
... |
symbol b |
$b的地址 |
@b的地址 |
%b的地址 |
函數(shù)b的地址 |
... |
... |
可以看到symbol b里存放了好幾個(gè)變量和函數(shù)的引用。在Perl里,symbol也可以被叫做glob。symbol b和symbal a可以分別用*b和*a表示。
glob的一個(gè)基本應(yīng)用是alias(別名):
$a = 10;
*b = *a;
print $b . "\n";
$b = 20;
print $a . "\n";
運(yùn)行結(jié)果:
符號(hào)表:
... |
... |
*a |
\$a |
... |
... |
*b |
\$a |
... |
... |
通過(guò)將引用賦給glob可以實(shí)現(xiàn)部分別名:
$a = 6;
@a = (1,2);
@b = (5,6);
print $a . "\n";
*b = \$a;
$b = 7;
print $a . "\n";
輸出:
符號(hào)表:
... |
... |
*a |
\$a |
\@a |
... |
... |
*b |
\$a |
\@b |
... |
... |
可以看到,只是標(biāo)量一樣了,數(shù)組還是各自的。
還可以用于參數(shù)傳遞:
sub change {
*b = shift;
$b = "cc";
}
$a = "tt";
print $a . "\n";
change(*a);
print $a . "\n";
運(yùn)行結(jié)果:
tt
cc
據(jù)說(shuō)通過(guò)glob傳遞參數(shù)要比傳引用快很多。
不同的作用域有不同的符號(hào)表:函數(shù)擁有自己的符號(hào)表,各個(gè)包也有自己的符號(hào)表。注意!詞法變量(lexical variable,用my關(guān)鍵字聲明的變量)不收入符號(hào)表。同時(shí),也不能用my關(guān)鍵字來(lái)聲明glob。my關(guān)鍵字只用來(lái)聲明詞法變量,glob不是詞法變量。
《Advance Perl Programming》第二版里說(shuō):可以把glob看成一個(gè)很有限的hash,他只有幾個(gè)key:SCALAR、ARRAY、HASH, IO, CODE, FORMAT和GLOB(筆者注:保存GLOB引用),另外還有兩個(gè)key:PACKAGE和NAME(筆者注:僅做自省用)。比如一個(gè)glob:a,*a{SCALAR}就相當(dāng)于\$a,*a{HASH}就相當(dāng)于\%a等等。
$a = 234;
print $a . "\n";
${*a{SCALAR}} = 345;
print $a . "\n";
輸出:
234
345
GLOB是Perl中幾個(gè)比較難的概念之一。在Perl的核心庫(kù)里,處處用到各種高深的glob技術(shù)。比如Exporter、AUTOLOAD、CORE等。雖然一般編程不需要用到特別深入的技術(shù)。如果能多了解一些,對(duì)于我們編程還是會(huì)大有益處的。