2011-03-02 75 views
3

名單方面,我發現在O'Reilly出版的一個例子有點怪異:標VS在Perl

@backwards = reverse qw/ yabba dabba doo /; 
print "list context: @backwards\n"; 
$backward = reverse qw/ yabba dabba doo /; 
print "scalar1 context: $backward\n"; 
$notbackward = qw/ yabba dabba doo /; 
print "scalar2 context: $notbackward\n"; 
print "print context: ",reverse qw/ yabba dabba doo /; 
print "\n"; 

輸出是:

list context: doo dabba yabba 
scalar1 context: oodabbadabbay 
scalar2 context: doo 
print context: doodabbayabba 

一個我不明白的是scalar1上下文:

這本書說'反向的東西'給出了一個列表上下文,所以我猜qw/ yabba dabba doo /被看作是一個列表和reverse qw/ yabba dabba doo /('doo','dabba','yabba')。

因此,$backward = something這意味着什麼是標量,所以我期待的結果'doo dabba yabba',但它是différent:'oodabbadabbay'。

我想,原因是因爲無法直接設置一個列表到標量。所以我做了scalar2測試:只打印列表中的最新項目。爲什麼?爲什麼不在scalar1測試中?

標量測試輸出如何工作?

回答

3

對於行:

$backward = reverse qw/ yabba dabba doo /; 

您在這裏從反向請求標。用於倒檔的perldoc說:

在標量環境符,連接LIST的 元素並返回一個字符串 值與在 相反的順序的所有字符。

所以它返回每個字母顛倒。對於 $ notbackward = qw/yabba dabba doo /; 的的perldoc爲QW //說:

計算結果爲提取出字符串的話 列表,使用 嵌入空格作爲字 分隔符。它可以被理解爲是 大致等效於:

   split(’ ’, q/STRING/); 

所不同的是它在 編譯時生成真實列表,並且在標量上下文它 返回列表中的最後一個元素。

因此請求標量只返回列表中的最後一項。

10

首先,qw/ yabba dabba doo /只是('yabba', 'dabba', 'doo')的語法糖。他們的意思是一樣的。

reverse函數帶有一個列表。在列表上下文中,它顛倒了列表。在標量上下文中,它會執行join('', @list),然後反轉該字符串中的字符並將其返回。

記住

$backward = reverse qw/ yabba dabba doo /; 
$notbackward = qw/ yabba dabba doo /; 

意味着

$backward = reverse ('yabba', 'dabba', 'doo'); 
$notbackward = ('yabba', 'dabba', 'doo'); 

reverse功能提供列表上下文和$notbackward =爲我們提供了標量上下文。這意味着逗號運算符在第一行的列表上下文和第二行的標量上下文中。在列表上下文中,comma operator創建一個列表。在標量上下文中,它評估兩個操作數並返回右邊的一個。這意味着標量上下文中('yabba', 'dabba', 'doo')的值爲'doo',這就是$notbackward的分配值。

7

所有Perl函數,包括您定義的所有subcan detect whether they are being called in "scalar" or "list" context,並且有許多函數根據此上下文來更改它們的行爲。

除了「我的意思」之外,關於何時以及如何以不同的方式處理兩個上下文(此whole thread on perlmonks對這些問題有很好的討論),有很少的約定,因此您需要依賴每個文檔函數來猜測一個函數在特定的上下文中會做什麼。

專門爲您的四個例子,

1. @backwards = reverse qw/ yabba dabba doo/
2. $backward = reverse qw/ yabba dabba doo/
3. $notbackward = qw/ yabba dabba doo /; 
4. print ..., reverse qw/ yabba dabba doo /; 

的行爲是

1. reverse function, list context:  returns list of the elements in reverse order 

2. reverse function, scalar context: concatenate argument list to a string, 
             return reverse of that string 

3. list assignment to scalar:   returns last element in list (*) 

4. also reverse function, list context same as #1 

(*) - 筆記列表分配給標爲陣列分配給不同的標量 - 這是一個列表陣列之間最重要的區別

@a = ("x", "y", "z"); $n = @a; # array assignment, $n is array size, or "3" 
$n = ("x", "y", "z");    # list assignment, $n is last element, or "z" 
0

爲了簡化其他答案,反向實際上做了兩件分開的事情,列表反轉和字符串反轉。

這已被證明是如此令人困惑,perl6將它們分解爲不同名稱的函數。