Perl编程语言

**Perl** 是高階、通用、直譯式、動態的程式語言家族。最初設計者拉里・沃爾為了讓在 UNIX 上進行報表處理的工作變得更方便，決定開發一個通用的手稿語言，而在 1987 年 12 月 18 日發表。目前，Perl 語言家族包含兩個分支 Perl 5 以及 Perl 6。雖然 Perl 不是正式的首字母縮略詞，但仍有各種各樣的逆向首字母縮略詞，包括「實用的提取和報告語言」。

Perl 借用了 C、sed、awk、shell 指令碼、Lisp 以及很多其他程式語言的特性。其中最重要的特性是 Perl 內部整合了正規表示式的功能，以及巨大的第三方代碼庫 CPAN。

2000 年開始，拉里・沃爾著手開發 Perl 6 來作為 Perl 的後繼，Perl 6 語言的語法有很多轉變，也被視為 Perl 家族中的另一個語言（Perl 6 於 2019 年更名為 Raku）。

Perl 語言應用廣泛，涵蓋 CGI、圖形編程、系統管理、網路編程、金融、生物等領域。由於其靈活性，Perl 被稱為手稿語言中的瑞士軍刀。

鑑於 Perl 在實際工程應用中廣泛使用，MacOS，Linux，FreeBSD 等現代化作業系統預設安裝 Perl。

## 歷史

### 早期版本

拉里・沃爾在 1987 年開始寫作 Perl，那時他正在 Unisys 當程式設計師，並且在 1987 年 12 月 18 日把 1.0 版本釋出到了 comp.sources.misc 新聞群組。這個語言在接下來的幾年內很快地發展起來。

沃爾最早的確把這個語言稱為「Pearl」（珍珠），因為他希望自己開發的語言有一個吉利的名字而且要儘量短小好記，他甚至聲稱早已考慮過所有三個及四個字母的詞彙，以及自己妻子的名字 Gloria。然而另一門語言 PEARL 早已存在，為了防止混淆，沃爾才把它改名 Perl。

Perl 2，於 1988 年釋出，特色是有一個更好的正規表示式引擎，Perl 3，於 1989 年釋出，添加了對二進位資料流的支援。

從前，Perl 唯一的文件是一個逐漸變長的手冊頁。在 1991 年，《Programming Perl》（被許多 Perl 程式設計師因封面稱為「駱駝書」），出版了，而且變成了一個真正的 Perl 語言的參考資料。同時，Perl 版本號變成了 4，不是因為這個語言的重大改變，而是因為這本書的特殊意義。

### 早期的 Perl 5

Perl 4 的一系列維護的版本，最後一版是 1993 年的 Perl 4.036。那時，沃爾廢棄了 Perl 4，開始開發 Perl 5。Perl 5 的最初始設計持續到了 1994 年。《_perl5-porters_》郵寄清單於 1994 年 5 月為了共同移植 Perl 5 而建立。這將主要的論壇留給了 Perl 5 的開發，維護，和移植。

Perl 5.000 於 1994 年 10 月 17 日釋出。這是一個幾乎完全重寫了的直譯器，而且它給這個語言添加了很多新的特性，包括物件，參照，局部變數，和模組。很重要地，模組提供了一個不用修改直譯器就可以擴充語言的方法。這使得核心的直譯器非常穩定，即使它允許一般的 Perl 程式設計師添加新的語言特性。從此，Perl 5 的開發就活躍起來了。

Perl 5.001 於 1995 年 3 月 13 日釋出。Perl 5.002 於 1996 年 2 月 29 日釋出，帶有參數類型的特性。這允許模組的作者寫出像 Perl 內部命令那樣智慧型的子程式。Perl 5.003 於 1996 年 6 月 25 日作為一個安全更新的版本釋出。

Perl 5 歷史中最重要的事件之一是支援了模組。在 1995 年 10 月 26 日，CPAN，一個釋出 Perl 模組的網站，建立了；截至 2015 年 11 月，它已經有超過 12457 個作者寫的 157794 多個模組了。

Perl 5.004 於 1997 年 5 月 15 日釋出，添加了 UNIVERSAL 包，這給了 Perl 一個所有的類的基礎和要求使用模組的特定版本的能力。另一個重要的開發是包括了 CGI.pm 模組，有助於 Perl 發展為一個 CGI 手稿語言。

Perl 現在也支援在 Microsoft Windows 和其它一些作業系統下運作。

Perl 5.005 於 1998 年 7 月 22 日釋出。這個版本包括了一個更好的正則引擎，一個編譯系統（通過 `B::*` 模組），`qr//` 正則參照運算子，一個基礎模組的選集，並且又支援了一些其它的作業系統，包括 BeOS。

### 2000 年至今

Perl 5.6 於 2000 年 3 月 22 日釋出。大的修改包括 64 位元支援，Unicode 字串支援，大檔案支援（即：超過 2GiB 的檔案）以及「our」關鍵字。在開發 Perl 5.6 的時候，開發組決定把版本名稱作成類似其它開源專案的；在 5.005\_63 版之後，下一個版本變成了 5.5.640，計劃是開發版本用奇數，穩定版本用偶數。

2000 年時，拉里・沃爾詢問社群對 Perl 新版本的建議。這個行程的結果在 361 RFC（評論請求）檔案里（這個檔案可以指導 Perl 6 的開發）。2001 年，工作開始於設計 Perl 6，一系列的檔案概述了新一代 Perl 里的改變和設計。它們是作為一期 RFC 被展示的，而不是一個正式文件。這時，Perl 6 的存在還只是一門語言的概述。

Perl 5.8 最初於 2002 年 7 月 18 日釋出，從此，每年才有一次更新。Perl 5.8 的最後一版是 5.8.9，釋出於 2008 年 12 月 14 日。Perl 5.8 改進了 Unicode 支援，添加了一個新的 IO 處理機制和新的多執行緒處理，提高了數字精度，添加了一些新模組。

2004 年，工作開始於提要 —— 原來的建議檔案，但後來變成了 Perl 6 語言的詳述。2005 年 2 月，唐鳳，開始開發 Pugs，一個用 Haskell 寫的 Perl 6 直譯器。這是最初的一個 Perl 6 實現。這個努力停止於 2006 年。

2007 年 12 月 18 日，Perl 1.0 的 20 周年紀念日，Perl 5.10.0 釋出了。Perl 5.10.0 包括了顯著的新特性，這拉近了 Perl 5 和 6 之間的距離。這些特性包括一個 switch 語句（叫做「given/when」），正規表示式的更新和智慧型匹配運算子「~~」。同時，另一個 Perl 6 的實現，Rakudo Perl 的開發開始了，一起使用 Parrot 虛擬機器開發。從 2009 年 11 月開始，Rakudo Perl 已經是每月一更新，現在已經是 Perl 6 的最完整的一個實現了。

Perl 5 開發過程中的一次大修改在 Perl 5.11；開發社群使用了每月更新的形式，這樣就可以提前預知 3 個月以內的釋出日期。

2010 年 4 月 12 日，Perl 5.12.0 釋出了。顯著的提升包括新的 `package NAME VERSION` 語法，Yada Yada 運算子（有意地用預留位置標記沒有實現的代碼），預設 `use strict;`（在 `use 5.012;` 時）完整的 Y2038 編譯，正則轉化多載，DTrace 支援，和 Unicode5.2。Perl 5.12.3 於 2011 年 1 月 21 日釋出；它包括了新版的模組和一些文件的改變。版本 5.12.4 於 2011 年 6 月 20 日釋出。

Perl 5.14 釋出於 2011 年 5 月 14 日。這個分支的最後一版，5.14.2，釋出於 2011 年 9 月 26 日。

Perl 5.16 釋出於 2012 年 5 月 20 日。顯著的新特性包括可以指定一個 perl 的版本來類比，這允許使用者更新 perl 的版本，但可以執行可能會不相容的老指令碼。Perl 5.16 也更新了核心部分來支援 Unicode 6.1。

### 名稱

Perl 原名叫「Pearl」。拉里・沃爾想給這個語言起一個有正面意思的短的名字；他考慮了（並且否定了）字典里每一個 3—4 個字母的詞。他也考慮用他的妻子 Gloria 的名字命名。沃爾在 Perl 官方釋出之前發現了現有的 PEARL 語言，並且改變了這個名字。

當指代這個語言的時候，名字通常是大寫的（**Perl**），就像專有名詞一樣。當指代這個直譯器本身的時候，這個名字通常是小寫的（**perl**），因為大部分類 Unix 檔案系統都是區分大小寫的。在《Programming Perl》的第一版釋出之前，用 **perl** 指代這個語言也很普遍；Randal L. Schwartz 排版時將這個語言的名字在書中寫成大寫的以便理解。後來，這個大小寫的區別就成為正規的了。

全大寫的「PERL」是有爭議的，而文件中說明「PERL」是不對的，一些核心的社群成員將其視為外行的標誌。這個名字偶爾會被視為「Practical Extraction and Report Language」的縮寫，就像文件頂端和一些紙質書本說的那樣。一些全稱被建議作為正式名稱，包括沃爾自己的幽默的「Pathologically Eclectic Rubbish Lister」。的確，沃爾要求這個名字啟示許多不同的擴充。

### 駱駝標誌

《_Programming Perl_》，由歐萊禮媒體釋出，特色是封面有一張駱駝的圖片，因而被稱作「駱駝書」。這張駱駝的圖片已經成為了 Perl 非官方的標誌和一個駭客的標誌，這出現在 T 恤衫和其它衣服上。

歐萊禮擁有此圖像之商標，並且宣稱，唯有在捍衛「符號之完整性」時，才會行使其法律上的權力。歐萊禮允許此商標在非商業目的之前提下被使用，並同時供了 Programming Republic of Perl 的圖像以及 Powered by Perl 的按鈕圖。Perl 的另一個識別符號是羊駝。因為《Intermediate Perl》一書的封面是一隻羊駝。

#### 洋蔥標誌

Perl 基金會擁有一個可選的標誌，一個洋蔥，允許它的子站點，Perl Mongers，PerlMonks，Perl.org 和其它網站使用。

## Perl 簡介

### Perl 語言的中心思想

Perl 語言的中心思想可以整合為一句話「**TMTOWTDI**」：

> There's More Than One Way To Do It. 
> （不只一種方法來做一件事。）
> 
> 

Perl 的作者拉里・沃爾建議可以把這個縮寫詞念成「Tim Toady」。這句話後來被擴充成:

> There's more than one way to do it, but sometimes consistency is not a bad thing either. 
> （不只一種方法來做一件事，但有時保持一致也不錯。）
> 
> * **TIMTOWTDIBSCINABTE**，發音為「Tim Toady Bicarbonate」.
> 

另一個 Perl 程式設計師常常想起的 Perl 俗語是：

> Easy things should be easy, and hard things should be possible. 
> （簡單的事情應該是簡單的，複雜的事情應該儘可能地變得簡單。）
> 
> 

### 優點

為了實現這樣的目標，並且又因為 Larry Wall 本人也是一個語言學家，他設計 Perl 語言時使用了很多語言學的思維。相比 C、Pascal 這樣的「進階」語言而言，Perl 語言直接提供泛型變數、動態陣列、Hash 表等更加便捷的編程元素。Perl 具有動態語言的強大靈活的特性，並且還從 C/C++、Basic、Pascal 等語言中分別借鑑了語法規則，從而提供了許多冗餘語法。使得程式設計師可以忽略電腦內部資料儲存、類型、處理方法、運算規則、甚至記憶體越界等等的細節，而將思考中心放在所需要的程式邏輯上。就這一點而言，很多 Perl 程式設計師認為目前只有 Perl、Python 等泛型語言才能稱為「進階」語言，而 C、Pascal 甚至 C++ 這些只能稱為「中進階」語言而已。可以說，在統一變數類型和掩蓋運算細節方面，Perl 做得比 Python 更為出色。

由於從其他語言大量借鑑了語法，使得從其他程式語言轉到 Perl 語言的程式設計師可以迅速上手寫程式並完成任務，這使得 Perl 語言是一門容易用的語言。

### 缺點

也正是因為 Perl 的靈活性和「過度」的冗餘語法，也因此獲得了僅寫（write-only）的「美譽」，因為 Perl 程式可以寫得很隨意（例如，變數不經宣告就可以直接使用），但是可能少寫一些字母就會得到意想不到的結果（而不報錯），許多 Perl 程式的程式碼令人難以閱讀，實現相同功能的程式碼長度可以相差十倍百倍，這就令程式的維護者（甚至是編寫者）難以維護。

同樣的，因為 Perl 這樣隨意的特點，可能會導致一些 Perl 程式設計師遺忘語法，以至於不得不經常檢視 Perl 手冊。對此，《Learning Perl》一書里建議經常使用 Perl 編程。

建議的解決方法是在程式裡使用 `use strict;` 以及 `use warnings;`，並統一代碼風格，使用庫，而不是自己使用「寫死」。Perl 同樣可以將代碼書寫得像 Python 或 Ruby 等語言一樣優雅。

## Perl 的語法

### Perl 的 Hello World 程式

下面是一個在標準輸出裝置上輸出 Hello World 的簡單程式，這種程式通常作為開始學習程式語言的第一個範例：

如果有 perl 5.10 以上的版本，也可以這樣：

這個程式將輸出一行字串：「Hello, world!」，以及一個換行。

### 變數

Perl 是一種無類型語言（untyped），換句話說，在語言層面上，Perl 和大多數程式語言不同，不把變數分成整數、字元、浮點數等等，而只有一種能接受各種類型資料的「無類型」變數。Perl 的變數以 $ 字元開頭。例如 `$a=5;``$b="Hello";``$c=3.2;``$d='\n这里并不换行';` 都是合法的 Perl 語句。

Perl 中各種變數的運算也很自由，數和含有數的字串是等效的，可以把數字字串參與數學計算，也可以反之，讓數字參與字串的構成和操作。

除單個變數（Perl 稱為純量「**Scalar**」）之外，Perl 還有兩種集合類型，分別是陣列（**Array**，用 @字元開頭）和關聯陣列（**Associative array**，或者稱為 **Hash**，用 % 開頭。類似 C++11 的 STL 無序表「**unordered\_map**」和 Python 的字典「**Dictionary**」）。陣列可以內含任意可變數目的變數，並以其儲存順序作為索引以完成常數時間的定位；而 Hash 表，則可以在變數之間建立一一對映，就像字典一樣，把不同的變數按照他們的邏輯關係組織起來，並以作為「鍵」的變數進行索引，完成常數時間的定位。

另外，Perl 還有一種特殊的類型，參照（reference），類似於指標，當作純量處理，可以指向純量（含參照）、陣列、Hash 等任何類型。如：

參照的好處在於，將它傳遞給函式之後，函式可以修改它指向的變數。而如果傳遞普通變數，修改的值只在函式內有效。

輸出「21」，即 foo () 內改變了 $foo。

### 判斷語句

因為 Perl 大量的創造冗餘的語法，並且從其他語言中大量的借鑑語法，使得 Perl 的語法極其豐富和靈活。Perl 共有下列幾種判斷語句：

* if 區塊

* if 語句

* unless 區塊

* unless 語句

* given/when(語句及區塊)

由於邏輯運算元的作用，還可以寫出不用關鍵字 if 或 unless 的判斷語句，如常用的打開檔案語句：

### 迴圈語句

Perl 中的迴圈語句也是非常的豐富。主要有：

Perl 自己的 for 或者 foreach 迴圈 (兩個完全一樣)：

從 C 語言借鑑來的 for 迴圈 (又可寫作 foreach，兩個完全一樣)：

while 迴圈：

do...while 迴圈：

until 迴圈：

從 PASCAL 語言借鑑來的 do...until 迴圈：

甚至還有利用動態語言特性，用 map 函式也可以做迴圈：

其實還有其他的迴圈方式。總而言之，就是 TMTOWTDI。

## Perl 的應用

Perl 主要應用在 Unix 平台和網頁中（PHP，CGI）。Perl 擁有海量的模組支援，在解決問題時非常方便。CPAN 有很多 Perl 模組。

### 以 Perl 編寫的軟體

* Bugzilla
* Movable Type
* TWiki
* Frozen Bubble

### Perl Data Language

Perl Data Language（簡稱 PDL）是 Perl 的一個外接模組，也是對 Perl 功能的一個重要拓展。它使得 Perl 語言可以直接對 2 至多維的矩陣直接操作，進行快速的矩陣運算，完成基礎的 Perl 所不能完成的運算，大大拓展了 Perl 的適用範圍。所以 PDL 本身也是很多其他模組的基礎。

而且 PDL 提供了與很多其他軟體套件的介面，例如 **FFTW**（一個快速傅立葉變換的軟體套件），又或者是 Mesa（Linux 上的 OpenGL 三維圖形彩現包），這些包原來往往僅提供 C/C++ 語言介面。這一功能使 PDL 成為拓展 Perl 功能的一個中間層。

## Perl 的社群文化

### Perl 詩經

和 C 語言一樣，在 Perl 界，難以讀懂的程式碼大賽是個有名的活動。近似難以讀懂的程式碼，但方向不同，Perl Poetry 是可以被 perl 編譯的詩。新的詩經通常會在 [1] 網站發表。

### JAPH

Just another Perl hacker（另一個 Perl 駭客）是一個和國際 C 語言混亂代碼大賽有著相同精神的社群文化。Perl 程式設計師通過寫 JAPH 代碼，來分享自己的編程技術。

## 競爭對手

因為許多 Perl 程式的代碼難以閱讀，加上它的物件導向功能被視為不是真正的物件導向 (只是模組的類比)，於是很多人拿 Perl 和其他動態語言來比較。

最常見的比較物件是 Python，有人寫了篇文章叫《What's wrong with Perl》，指出 Perl 的缺點，鼓勵別人學 Python。著名駭客埃里克・史蒂芬・雷蒙寫了《Why Python?》，該文中一個重要的比較物件就是 Perl。《A Byte Of Python》里的《Why Not Perl?》也把 Python 和 Perl 比較。

Ruby 的作者（松本行弘，Matz）甚至直認他想 Ruby 作為 Perl 的後繼者。

## Raku（舊名 Perl 6）

2000 年開始，拉里・沃爾著手開發 Perl 6 來作為 Perl 的後繼，2019 年更名為 Raku。

在 Perl 的官網介紹中，Raku 不是 Perl 5 的下一個版本，而是與 Perl 5 並列開發的另一種程式語言。
Raku 更好地支援物件導向，有專用於定義類的語法：

Raku 可以明確定義變數類型，當類型不匹配，編譯時報錯。

另外，Raku 提供了不同的正規表示式語法，新的語法稱作「規則」，並且允許使用者在正規表示式中加入空格等以便閱讀，還可以命名一個正規表示式方便呼叫。

Raku 中的控制流程和迴圈的判斷條件的括號可選:

但是如果加入括號，不能緊跟在關鍵字後面，而要空一格，因為用 foo () 這樣的形式，編譯器辨識為呼叫函式 foo，而不管它是不是關鍵字：

## 參考文獻

## 參見

* CPAN
* Perl 6（Raku）
* Parrot 虛擬機器

## 外部連結