Provided by:
manpages-zh_1.5-1_all 
NAME
perldata - Perl 數據類型
DESCRIPTIONyz
Variable namesqW
Perl 有三種內建的數據類型:標量,數組和關聯數組(即
"哈希表,hash")。數組以數字為索引,通常以0開始,升序排列。哈希表以與-
袺鶬p的字符串為索引,內部排列是無序的。
q常通過一蚥僆q名(或變量名的引用)來引用。變量名的前綴字符顯示了-
獐矞型。其餘部分指明了引用的是一荅S定的C通常變量名是一-
荌艉@的標識符,以字母或下劃線開始,包括字母、下劃線和數字。某些情況下,也可以是以
"::" 分隔的一串標識符(或者是過時的 "'");除了最後一-
荂A其它都是包名,用來定位最後一蚍陏挐觼狾b的位置(詳情參見 perlmod 中的
Packages)。可以用一蚋眾瑼獐陏挐襯荋壎N它,利用引用就可以。下文有詳-
z,也可參見 perlref .
Perl 也有內建的變量,其名稱不遵循這一規則。它-
怞W稱古怪,這樣可以避免與你的變量名沖突。模式匹配中被匹配到的字符串是以
"$" 加一蚍r的變量名來存放的(參見 the perlop manpage 和 the perlre
manpage)。 另外,還有幾茖洇A可以介入perl
內部工作的特殊變量,其名稱中包含標點和控制字符(參見 perlvar )
標量以 '$'開始, 即使它是數組或哈希的元素也是如此。可以把 '$' 理解為‘s'
,表示scalar(標量)。(譯者注:此處根據有關文件,做了改動,下-
悸愿處也是這樣)
$days # 簡單標量 "days"
$days[28] # 數組 @days的第29茪葛
$days{'Feb'} # 哈希 %days的 ‘Feb‘ 所對應的
$#days # 數組 @days的最後一茪葛尷滲薑瘏
整蚍捸]或數組和哈希的局部)以 '@'開始, 它類似^文中的 "these" 或
"those" (這些……那些……),表示期望有多蚧。
@days # ($days[0], $days[1],... $days[n])
@days[3,4,5] # 即 ($days[3],$days[4],$days[5])
@days{'a','c'} # 即 ($days{'a'},$days{'c'})
整茷╡H '%' 開始:
%days # (key1, val1, key2, val2 ...)
另外,子程式以'&'來表示, 但有時在不引起誤解的情況下也可以不用, 就像
"do" 在^語中常常省略一樣。 符號表項以 '*' 作為開始字符,
不過你現在還不用關心這 (if ever ;-)
每一種數據類型都有它自己的名字空間,常量標識符也一樣。這意味著你可以使用同一-
茼W字來命名標量、數組、哈希、檔案句柄、目錄句柄、子程式、格式或標簽。即
$foo 和 @foo 是不同的變量。也即意味著 $foo[1] 是 @foo 的一部分, 而不是
$foo的一部分. 這看來有些怪異,不過很正常,因為它本來就怪異。
因為變量名以 '$', '@', 或 '%'開始,
保留詞對變量沒有什麼影響。保留詞影響的是標簽和檔案句柄,因為它-
怳ㄛO以特殊字符前綴開始的。你不能用 "log"
來命名檔案句柄,因為它是保留詞(提示:你可以用 "open(LOG,'logfile')"
而不是 "open(log,'logfile')").
使用大寫的檔案句柄既增加了可讀性,又減少了沖突的發生。大小寫是有意義的--"FOO",
"Foo", 和 "foo"
是不同的名稱。以字母或下劃線開始的名稱可以包含數字和下劃線。
可以用一茠藀^相關引用的表達式來替換這樣的變量名。參見 perlref
以數字開始的變量名只能包含數字。不是以字母、下劃線或數字開始的變量名只能含有一-
茼r符,如: $% 或 $$. (大部分這樣的變量都有特殊的意義。例如,$$
是當前進程的id。)
ContextWU文
在 Perl 中有時操作或熒N義取決於該操作或珜B的上下文。有兩茈D-
n的上下文:列表和標量上下文。相當一部分操作在需-
n列表的上下文中返回列表,在需-
n標量的上下文中返回標量。這在有關該操作的文件中會提到。換句話講,Perl會-
姜這些操作符。^語中的某些詞,如‘fish’和‘sheep’與此類似。
操作可以根據不同的上下文返回不同的C例如,如果這樣寫:
int( <STDIN> )
integer 操作提供標量上下文給 <> 操作符, <> 會從STDIN 讀入一行返回給
integer 操作,然後它返回其中的整型量。但如果你這樣寫:
sort( <STDIN> )
sort操作提供列表上下文給<>,
<>會讀入STDIN中的每一行直到結束,然後將其傳遞給sort,sort然後將其排序輸出。
賦騆特殊,左側的參數決定了右側的參數的上下文。賦-
匱迠q,則右側參數的上下文是標量上下文;賦-
匱晥峆╡A則右側參數的上下文是列表上下文。賦-
髡C表(或片段,其實也是列表),右側的上下文也是列表上下文。
當你使用 "use warnings" 編譯指示或 Perl 的 -w
參數時,你可能會看到這樣的警告:在 "無效的上下文,void context"
中使用了常量或函數。無效上下文的意思是Q丟棄不用,比如只包含有
""fred";" 的語句; 或是 "getpwuid(0);";. 在-
n求列表上下文的函數被標量上下文環境調用時,也會出現這蚅筆i.
使用者定義的子程式可能會需-
n查看上下文是無效,標量,還是列表。不過,大多數並不需-
n這麼做。因為標量和列表會自動插入到一茼C表中。參見 perlfunc 中的
"wantarray" 以了解如何辨明你的函數調用時的上下文。
Scalar valuesq
Perl 中的所有數據都是標量, 標量的數組,標量的哈希. 標量可以是三種不同的-
: 數字, 字符(串), 引用. 通常, 不同孜〞甄鉥型O透明的. 雖然一-
蚍迠q不可能有多蚧, 但是它可以是一茈]含多蚧的數組或哈希的引用.
標量不一定非此即彼. 不需-
n聲明變量的類型是"字符串","數字","引用"或其它什麼. 因為標量會自動轉換,
所以其類型不用關心. Perl
是上下文多形語言,它的標量可以是字符串,數字或引用(包括對象).
其中字符串和數字在大多數情況下並沒有什麼不同,
引用是強化的,不可變的帶有內建引用p數和析構器的指針.
標量在不是空字符串和數字0的時堀Q解釋為真 TRUE.
布爾上下文是這樣一種上下文, 這時不會發生數字或字符串的自動轉換.
有兩種空字符串(有時以"empty"表示), 定義了的和未定義的.
定義了的空字符串就是長度為零的字符串,如"". 未定義的空字符串是一蚧,這-
磳頇Y事物並沒有真實P它對應, 比如出錯, 或到達檔案尾, 或者你引用一-
茈憬w義的數組或哈希的元素時,都會返回一茈憬w義的空字符串. 雖然在朽簌erl
中,在n求已定義變量的上下文中使用未定義的變量可以使得該變量得到定義,
現在卻只有在特殊的情況下才會出現這種結果,參見the perlref manpage.
可以用defined()
函數來檢測標量是否已經定義(對數組和哈希無效),也可以用undef()
去除對變量的定義.
n弄清楚一茼r符串是否是有效的非0數字,只n看它是不是數字0和字母 "0"
就足夠了(不過這在使用-w參數時,會顯示警告). 因為非數字的字符串被看作0,
與awk中相似:
if ($str == 0 && $str ne "0") {
warn "That doesn't look like a number";
}
這種方法可能是最好的,因為如Y不然你不會正確對待 IEEE 的注釋,比如 "NaN"
和無窮大. 別的時, 你可能更願意用 POSIX::strtod()
函數或是正則表達式來檢測字符串是否能用做數字(參見perlre).
warn "has nondigits" if /\D/;
warn "not a natural number" unless /^\d+$/; # rejects -3
warn "not an integer" unless /^-?\d+$/; # rejects +3
warn "not an integer" unless /^[+-]?\d+$/;
warn "not a decimal number" unless /^-?\d+\.?\d*$/; # rejects .2
warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
warn "not a C float"
unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
數組的長度是標量. 通過$#days你可以知道@days的長度.
技術上講,這不是數組的長度; 而是最後一茪葛尷漱U標,因為第一-
茪葛尷漱U標是0. 對$#days 賦|改變數組的長度. 以這種方式減少數組的話,
會破壞其中的, 再增加其長度也不能恢復. (Perl 4中是可以的, 我-
怬幭雂F它以確保析構器被及時調用.)
你可以使用一些小技巧來預擴展一蚍(如果你知道它將會變得很大的話).
可以用給超出數組S圍的元素賦漱隤k擴展數組. 可以給數組賦@-
茠臟C表以清空數組. 下掩y句等價:
@whatever = ();
$#whatever = -1;
數組處於標量上下文中時, 返回O數組的長度. (列表在標量上下文中,返回-
O列表的最後一茪葛,像是C中的逗號操作符, 而內建函數的返回悒-
怞菑v決定.) 以下語句為真:
scalar(@whatever) == $#whatever - $[ + 1;
Perl 5 改變了 $[ 的意義: 不必擔心別的程式改變了 $[ 的.
(換言之,不推薦使用 $[ ) 所以,可以寫成這樣:
scalar(@whatever) == $#whatever + 1;
有些程式為了明確起見, 會使用顯式的轉換:
$element_count = scalar(@whatever);
當哈希處於標量上下文中時, 如果哈希為空, 返回偽, 如果非空, 返回偺u;
說得更精確些, 返回O茼r符串,
由已經使用的存儲段和分配的全部存儲段組成,二者之間以斜槓分隔.
這可以用來反映Perl的哈希算法的好壞. 例如, 你的哈希中有10,000茪葛,但是
%HASH 的標量 "1/16", 則說明僅用到了16茼s儲段中的一, 也許10,000-
茪葛應ㄕb這一茼s儲段中. 最好不n發生這種情況.
你可以預先為哈希分配空間, 這n使用給 keys() 函數賦漱隤k來實現.
實際分配的空間是大於所給漱G的鴃G
keys(%users) = 1000; # 分配 1024 空間
Scalar value constructorsqcy
數`量有以下浮點和整數格式:
12345
12345.67
.23E-10 # a very small number
3.14_15_92 # a very important number
4_294_967_296 # underscore for legibility
0xff # hex
0xdead_beef # more hex
0377 # octal
0b011011 # binary
在數字常量中可以在數字間插入下劃線來增加可讀性。例如,可以三位一組
(Unix 樣式的分組,例如 0b110_110_100),或者四位一組 (來表示
nibbles,例如 0b1010_0110),或者其他分組。
字符串通常以單引號或雙引號括起. 與標準Unix shells中的引號相似:
雙引號可以接收轉義和變量; 單引號不可以 (除了 "\'" 和 "\\")). C
樣式的轉義字符可以用來輸入新行,跳格等字符,轉義字符的列表可以參見
perlop 中的 "Quote and Quote-like Operators"
十六進制,八進制,或二進制以字符串形式表示(如:'0xff'),不能自動轉換為十進制形式.
hex() 和 oct() 函數可以實現轉換. 參見 perlfunc 中的 hex 和 oct
了解詳情.
可以在字符串中直接加入新行.
字符串中的變量只能是標量,數組和數組或哈希的片段 (換言之, 以$或@開始,
後跟下標.). 以下語句列印``The price is $100.''
$Price = '$100'; # not interpolated
print "The price is $Price.\n"; # interpolated
perl 中沒有 double interpolation,因此 $100 保持不變。
正如在有些shell中一樣, 你可以用花括號括起變量名,
以便區分變量名和其後的字母及下劃線. 如果n將一-
蚥僆q改寫為字符串時,必須這樣做,以避免與後-
悸甄躩_號或單引號連接起來,否則會被當作包名:
$who = "Larry";
print PASSWD "${who}::0:0:Superuser:/:/bin/perl\n";
print "We use ${who}speak when ${who}'s here.\n";
如果沒有花括號, Perl會尋找 $whospeak, $who::0, 和 $who's 變量. 後兩-
茯O不存在的 who 包中的$0 和 $s.
實際上, 花括號中的標識符必須是字符串, 哈希的下標也必須是字符串. 都不需-
n引號, 前悸漕狺l$days{'Feb'} 可以寫作 $days{Feb} 引號會自動加上.
但是下標中的其它復雜內容被解釋為表達式.
Version Strings
`N: Version Strings (v-strings) have been deprecated. They will not
be available after Perl 5.8. The marginal benefits of v-strings were
greatly outweighed by the potential for Surprise and Confusion.
類似 "v1.20.300.4000" 這樣的形式被解釋為一茼r符串. 這種形式稱為
v-strings,提供了更易讀的方法來構造字符串,比起
"\x{1}\x{14}\x{12c}\x{fa0}" 更加易讀. 這在表示 Unicode 字符串時很有用,
在使用字符串比較命令("cmp", "gt", "lt" 等)比較版本號時也非常有用.
如果其中的點號多於兩, 則開始的 "v" 可以省略.
print v9786; # prints UTF-8 encoded SMILEY, "\x{263a}"
print v102.111.111; # prints "foo"
print 102.111.111; # same
這種形式可以用於require 和 use 中作版本檢查."$^V"
特殊變量中的Perl版本號就是以這種形式保存的. 參見 perlvar 中的 "$^V"
注意使用 v-strings 來保存 IPv4 地址是不可移植的,除非同時使用 Socket
包的 inet_aton()/inet_ntoa() 函數。
注意從 Perl 5.8.1 開始單蚍r的 v-strings (類似 "v65") 如果在 "=>"
操作符(通常用來從 hash 什洃懦} hash 鍵) 之前,不是一
v-strings,而是解釋為字符串 ('v65')。在 Perl 5.6.0 到 Perl 5.8.0
它一直是 v-strings,但是這樣帶來了更多混淆和錯誤而不是優點。多蚍r的
v-strings,類似 "v65.66" 和 65.66.67,繼續總是被當作 v-strings
S`q
特殊變量 __FILE__, __LINE__, 和 __PACKAGE__ 代表當前檔名,行號,和包名.
它怚u能作為單獨的符號來使用; 不能用於字符串中內插. 如果沒有當前包(用
"package;" 指令來實現), 則__PACKAGE__ 是一茈憬w義的.
控制字符 ^D 和 ^Z, 以及 __END__ 和 __DATA__ 變量可以表示檔案的邏輯結束.
其後的文本被忽略.
__DATA__ 之後的文本可以通過檔案句柄 "PACKNAME::DATA" 讀取, "PACKNAME"
是 __DATA__ 所在的包的名稱. 句柄指向__DATA__ 後悸漱憟.
讀取結束程式會自動關閉該句柄 "close DATA". 為了與 __DATA__
還沒有出現以前已經存在的程式相容, __END__ 在頂級稿本中與 __DATA__
性質相同(在用 "require" 或 "do" 調用時是不同的) 不過可以通過
"main::DATA" 來調用其中的內容.
參見 SelfLoader 詳細了解 __DATA__, 其中還有例子. n注意在BEGIN
塊中無法讀取DATA句柄: 因為BEGIN 塊在編譯時即被執行, 而此時 __DATA__ (或
__END__) 還未被程式看到.
r
在文法上沒有特殊意義的詞語都被看作字符串. 稱之為 "裸詞".
和檔案句柄以及標簽一樣,
僅包含小寫字母的裸詞有可能在將來與程式中的保留詞發生沖突,
實際上,當你使用 "use warnings" 語句,或是 -w 選項時, Perl會對此提出警告.
一些人可能希望完全禁止這樣的詞. 如果有如下語句:
use strict 'subs';
那麼不能被解釋為子程式的裸詞會引起編譯時錯誤. 這種制到塊結束時終止.
而內部的塊可以撤消這一制, 用"no strict 'subs'"
Xj
數組和序列被合並為雙引號引用的字符串時,以變量 $" 指定的 (如果指定了
"use English;" 那麼是 $LIST_SEPARATOR 的)
作為分隔符,預設是空格。下列語句等價:
$temp = join($", @ARGV);
system "echo $temp";
system "echo @ARGV";
在搜索模式中(在雙引號字符串中也是)有一茤鶷V淆之處: "/$foo[bar]/" 應該是
"/${foo}[bar]/" ("[bar]" 是正則表達式的字符類) 還是 "/${foo[bar]}/"/
("[bar]" 是數組 @foo 的下標) 呢? 如果 @foo 不存在,
那很明顯它應該是字符類. 如果 @foo 存在, Perl 會盡力猜測 "[bar]" 的含義,
且它幾乎總是對的. 如果它猜錯了, 或者你比較偏執, 你可以使用花括號.
here-document 的語法已經被移動到 perlop 中的 "Quote and Quote-like
Operators"
List value constructorsCcy
列表是用逗號分開的各蚧組成的(如果優先級需n的話,外掄揈用圓括號包圍):
(LIST)
在不需n列表的上下文中, 列表的O最後一茪葛尷瘓,
這與C中的逗號操作符類似. 例如:
@foo = ('cc', '-E', $bar);
將列表賦給數組@foo, 但是
$foo = ('cc', '-E', $bar);
將$bar 的廘$foo. 注意, 數組在標量上下文中的O數組的長度;
下例將3賦給$foo:
@foo = ('cc', '-E', $bar);
$foo = @foo; # $foo gets 3
列表的最後可以輸入逗號, 所以這樣也是正確的:
@foo = (
1,
2,
3,
);
n將here-document 賦給數組, 一行作為一茪葛, 可以這樣作:
@sauces = <<End_Lines =~ m/(\S.*\S)/g;
normal tomato
spicy tomato
green chile
pesto
white wine
End_Lines
列表會自動插入子列表. 也即, 下例將展開數組,哈希等, 並將其中的每一-
茪葛嬪@為該新列表的一茪葛. 數組或哈希失去其鴩茠漕份.列表
(@foo,@bar,&SomeSub,%glarch)
包括@foo,@bar的每一茪葛,包括函數 SomeSub 返回C表的每一茪葛, 包括
%glarch 的每一茼r. n想使用不內插的列表, 可以參見 perlref
空列表可以表示為(). 在列表中插入空列表沒有意義. ((),(),()) 與()相同.
同樣, 內插一茠髒掑]沒有意義.
合並的語法表示開和閉括號都是可選的 (除非為表示優先級需-
n);而列表可以以可選的逗號結束表示列表中的多茬r號是合法的語法。列表
"1,,3" 是兩茼C表的並置,"1," 還有 3, 第一茈H可選的逗號結束。"1,,3" 是
"(1,),(3)" 也是 "1,3" (類似的,"1,,,3" 是 "(1,),(,),3" 也是 "1,3" 等等)
不過我怳ㄚ媊釦A使用這麼混亂的寫法
列表也可以像數組一樣使用下標. 為了避免歧義需n在列表外使用括號. 例如:
# Stat returns list value.
$time = (stat($file))[8];
# SYNTAX ERROR HERE.
$time = stat($file)[8]; # OOPS, FORGOT PARENTHESES
# Find a hex digit.
$hexdigit = ('a','b','c','d','e','f')[$digit-10];
# A "reverse comma operator".
return (pop(@foo),pop(@foo))[0];
可以給列表賦, 當然列表中的每茪葛壎眸椰X法才行:
($a, $b, $c) = (1, 2, 3);
($map{'red'}, $map{'blue'}, $map{'green'}) = (0x00f, 0x0f0, 0xf00);
特例是可以賦 "undef"。當忽略程式的某些返回伈o很有用:
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
列表賦B於標量上下文中時, 返回O等號右側的表達式的元素蚍:
$x = (($foo,$bar) = (3,2,1)); # set $x to 3, not 2
$x = (($foo,$bar) = f()); # set $x to f()'s return count
這在布爾上下文中很方便, 因為多數列表函數在結束時返回空列表, 這時列表賦-
|返回0, 被解釋為FALSE.
它也是一茼野峈熔葴D的來源,就是在列表上下文中執行一-
茖蝻徆犑@,然後記錄返回碩數,方法是為一茠臟C表賦-
A然後在標量上下文中使用這蚧。例如,如下代碼:
$count = () = $string =~ /\d+/g;
將置 $count 為 $string 中找到的數字組數量。這樣能行的-
鴞]是模式匹配是列表上下文 (因為它被賦予一-
茠臟C表),因此返回所有匹配部分的列表。在標量上下文中的列表賦-
N它轉換為元素的蚍 (這裏是模式被匹配的數量),然後賦
$count。注意簡單地使用
$count = $string =~ /\d+/g;
沒有作用,因為在標量上下文中的模式匹配只會返回 true 或
false,而不是所有的匹配。
最後一茪葛壎i以是數組或哈希:
($a, $b, @rest) = split;
my($a, $b, %rest) = @_;
當然可以在任何位置使用數組或哈希, 不過第一蚍晥峆╡|將所有的-
ˇ甯陘v有, 其它的元素都會變為undefined.這在my() 或 local()中或許有用.
哈希可以用含有字麊漲C表來初始化:
# same as map assignment above
%map = ('red',0x00f,'blue',0x0f0,'green',0xf00);
列表和數組交互性很強, 哈希則不然.
你可以像使用數組時一樣對列表使用下標並不意味著可以像使用哈希一樣使用列表.
同樣,處於列表中的哈希總是以字麊漣峖&i開. 因此有時使用引用n更好一些.
通常在字鴾尹洏 "=>" 操作符會更易讀. "=>" 與逗號作用相同,
不過它還有一荍@用, 那就是可以使它左側的對象被解釋為字符串 --
如果該對象是裸字的話,將是合法的標識符 ("=>"
不引用包含雙冒號的復合標識符). 這在初始化哈希時棒極了:
%map = (
red => 0x00f,
blue => 0x0f0,
green => 0xf00,
);
或者初始化哈希的引用:
$rec = {
witch => 'Mable the Merciless',
cat => 'Fluffy the Ferocious',
date => '10/31/1776',
};
or for using call-by-named-parameter to complicated functions:
$field = $query->radio_group(
name => 'group_name',
values => ['eenie','meenie','minie'],
default => 'meenie',
linebreak => 'true',
labels => \%labels
);
注意哈希初始化時的順序和輸出時的順序並不一定相同.
n得到順序的輸出可以參見 perlfunc 中的 "sort"
SubscriptsU標
數組可以用一-
茯元符號,加上它的名字(不包括前導的"@"),加上方括號和其中包含的下標來取得-
C例如:
@myarray = (5, 50, 500, 5000);
print "Element Number 2 is", $myarray[2], "\n";
數組下標從 0 開始。tU標返回從尾部開始數的C在我-
怐漕狺l中,$myarray[-1] 將是 5000, $myarray[-2] 是 500。
Hash 下標與此類似,但是不使用方括號而是花括號。例如:
%scientists =
(
"Newton" => "Isaac",
"Einstein" => "Albert",
"Darwin" => "Charles",
"Feynman" => "Richard",
);
print "Darwin's First Name is ", $scientists{"Darwin"}, "\n";
Slicesq
通常對哈希或數組一次訪問一茪葛. 也可以使用下標對列表元素進行訪問.
$whoami = $ENV{"USER"}; # one element from the hash
$parent = $ISA[0]; # one element from the array
$dir = (getpwnam("daemon"))[7]; # likewise, but with list
片段可以一次訪問列表,數組或哈希中的幾茪葛, 這是通過列表下標來實現的.
這比分別寫出每蚧n方便一些.
($him, $her) = @folks[0,-1]; # array slice
@them = @folks[0 .. 3]; # array slice
($who, $home) = @ENV{"USER", "HOME"}; # hash slice
($uid, $dir) = (getpwnam("daemon"))[2,7]; # list slice
既然可以給列表賦, 當然也可以哈希或數組的片段賦.
@days[3..5] = qw/Wed Thu Fri/;
@colors{'red','blue','green'}
= (0xff0000, 0x0000ff, 0x00ff00);
@folks[0, -1] = @folks[-1, 0];
上悸瑣犑@與下列語句等價:
($days[3], $days[4], $days[5]) = qw/Wed Thu Fri/;
($colors{'red'}, $colors{'blue'}, $colors{'green'})
= (0xff0000, 0x0000ff, 0x00ff00);
($folks[0], $folks[-1]) = ($folks[-1], $folks[0]);
既然改變片段就會改變數組或哈希的鴝l, 那麼 "foreach"
結構可以部分或全部地改變數組或哈希的.
foreach (@array[ 4 .. 10 ]) { s/peter/paul/ }
foreach (@hash{qw[key1 key2]}) {
s/^\s+//; # trim leading whitespace
s/\s+$//; # trim trailing whitespace
s/(\w+)/\u\L$1/g; # "titlecase" words
}
空列表的片段還是空列表, 因此:
@a = ()[1,0]; # @a has no elements
@b = (@a)[0,1]; # @b has no elements
@c = (0,1)[2,3]; # @c has no elements
但是:
@a = (1)[1,0]; # @a has two elements
@b = (1,undef)[1,0,2]; # @b has three elements
下例利用了這一特性,當返回空列表時循環終止:
while ( ($home, $user) = (getpwent)[7,0]) {
printf "%-8s %s\n", $user, $home;
}
我怞b前掩★L, 標量上下文中的列表賦藀^O右側的元素蚍.
空列表沒有元素, 所以當口令檔案讀完後, 返回O0而不是2.
為什麼對哈希的片段使用'@'而不是'%'呢.
因為括號的類型(方括號或花括號)決定了它是數組還是哈希.
而數組或哈希的開始字符('$'或'@')表示返回O單蚧還是多蚧(列表).
Typeglobs and FilehandlesMy`
Perl 使用叫做 全局類型 的類型來支持整茞顫鼓穚. 全局類型的前綴是*,
因為它表示所有的類型. 這在過去通常用來給函數傳遞數組或哈希的引用,
但是現在有了真正的引用, 這就幾乎不需n了.
現在,全局類型的主n用途是創建符號表別名. 如下賦:
*this = *that;
使得$this 成為 $that的別名, @this 成為 @that的別名,%this 成為
%that的別名, &this 成為 &that的別名, 等等. 使用引用會更安全. 這樣:
local *Here::blue = \$There::green;
暫時使 $Here::blue 成為 $There::green的別名, 但不會使 @Here::blue 成為
@There::green的別名, 也不會使 %Here::blue 成為 %There::green的別名,
等等. 參見 perlmod 中的 Symbol Tables 有多茖狺l. 看起來可能有些怪異,
不過這卻是整胺mport/export系統的基礎.
全局類型的其它用途還有, 給函數傳輸檔案句柄或是創建新的檔案句柄. 如果你-
n使用全局類型代替檔案句柄, 可以這樣做:
$fh = *STDOUT;
或者使用真正的引用, 像這樣:
$fh = \*STDOUT;
參見 perlsub 有關於間接句柄的多茖狺l.
全局類型也是使用local() 創建局部檔案句柄的一種方法. 作用-
S圍在當前塊之內, 但是可以被傳回.例如:
sub newopen {
my $path = shift;
local *FH; # not my!
open (FH, $path) or return undef;
return *FH;
}
$fh = newopen('/etc/passwd');
既然我怞*foo{THING} 這樣的記法,
全局類型不再多用於檔案句柄,但在從函數傳出或向函數傳入新的檔案句柄時它還是必需的.因為*HANDLE{IO}
只有在HANDLE 已經是檔案句柄時才起作用. 換言之,
在建立新符號表項時必須使用 *FH; *foo{THING} 是不行的. 不知道該用誰時,
使用 *FH
所有能創建檔案句柄的函數 (open(), opendir(), pipe(), socketpair(),
sysopen(), socket(), 和 accept()) ,在傳遞給它-
怐漸y柄是標量時,會自動創建一荌峖W句柄. 這使得像open(my $fh, ...) 和
open(local $fh,...) 這樣的結構可以創建一茼b超出-
S圍時可以自動關閉的句柄,如果沒有另外的對它怐漱犍峈爾.
這大大減少了全局類型的使用,當需n打開一茈i以到處使用的句柄時,
可以這樣做:
sub myopen {
open my $fh, "@_"
or die "Can't open '@_': $!";
return $fh;
}
{
my $f = myopen("</etc/motd");
print <$f>;
# $f implicitly closed here
}
注意如果使用了初始化的標量,那麼結果會有不同:"my $fh='zzz'; open($fh,
...)" 與 "open( *{'zzz'}, ...)" 等價。"use strict 'refs'"
禁止了這樣做。
另一茬衎堸峖W句柄的方法是用Symbol 模塊或IO::Handle
模塊或諸如此類的東西. These modules have the advantage of not hiding
different types of the same name during the local(). 在 open() in the
perlfunc manpage 的文末有-
茖狺l.(譯者注:說實話,對匿名句柄我現在也是一頭霧水,翻譯的不當之處,請高手指出.)
SEE ALSO見
參見 the perlvar manpage 了解 Perl的內建變量和合法變量。參見the perlref
manpage, the perlsub manpage, 和 Symbol Tables in the perlmod manpage
了解全局類型和 *foo{THING} 語法。
@H
redcandle <redcandle51@nospam.chinaren.com>
ss
2001124http://cmpp.linuxforum.net