Perl

Perl 是高階、通用、直譯式、動態的程式語言家族。最初設計者拉里・沃爾為了讓在 UNIX 上進行報表處理的工作變得更方便，決定開發一個通用的指令碼語言，而在 1987 年 12 月 18 日發表。目前，Perl 語言家族包含兩個分支 Perl 5 以及 Raku。

關於 Perl 名字的由來，有很多說法。雖然 Perl 不是正式的首字母縮略詞，但仍有各種各樣的逆向首字母縮略詞，包括 “實用的提取和報告語言”。

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

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

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

歷史

1.1 早期版本

拉里・沃爾在 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，不是因為這個語言的重大改變，而是因為這本書的特殊意義。

1.2 早期的 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 具有優秀的跨平臺特性。Perl 現在支援在 Microsoft Windows、蘋果公司的 MacOS、GNU/Linux 和其它一些作業系統下運作。

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

1.3 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 之間的距離。這些特性包括一個（叫做 “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。

1.4 名稱

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

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

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

1.5 駱駝標誌

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

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

1.5.1 洋蔥標誌

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

Perl 簡介

2.1 Perl 語言的中心思想

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

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

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

2.2 優點

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

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

2.3 缺點

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

同樣的，因為 Perl 這樣隨意的特點，可能會導致一些 Perl 程式設計師遺忘語法，以至於不得不經常檢視 Perl 手冊。對此，《Learning Perl》一書裡建議經常使用 Perl 程式設計。建議的解決方法是在程式裡使用 use strict; 以及 use warnings;，並統一程式碼風格，使用庫，而不是自己使用「硬編碼」。Perl 同樣可以將程式碼書寫得像 Python 或 Ruby 等語言一樣優雅。

Perl 的語法

3.1 Perl 的 Hello World 程式

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

!/usr/bin/env perl

print "Hello, world!\n";

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

!/usr/bin/env perl

use 5.010;

say "Hello, world!";

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

3.2 變數

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 等任何型別。如：

$foo = \$bar; print $$foo;

$foo = \@bar; print @$foo;

$foo = \% bar; print %$foo;

$foo = \&bar; print $foo->;

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

sub foo

{

my $var = shift;

$$var = '1';

}

my $foo = '2';

my $var = \$foo;

print $$var;

foo ($var);

print $foo;

輸出 “21”，即 foo 內改變了 $foo。

3.3 判斷語句

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

if 區塊

if ($hour> 22) {print "should sleep...\n";}

if 語句

print "hello" if $guest >= 1;

unless 區塊

unless ($credit> 100) {print "You can not graduate!\n";}

unless 語句

print "eat\n" unless $food == 0;

given/when (語句及區塊)

use 5.010;

given ($foo)

{

say 'a' when 'a';

when (/b/) {say 'b';} #when 可以寫成語句或區塊

default {say 'not match';} #只可以寫成區塊。

}

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

open DATA, '

3.4 迴圈語句

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

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

@group = 1 .. 10;

for (@group) {print "$_\n";}

print "$_\n" for @group;

foreach (@group) {print "$_\n";}

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

for ($i = 0; $i

while 迴圈：

$i=0;

while ($i

do...while 迴圈：

$i = 0;

do {

print "$group$i\n";

$i++;

} while ($i

until 迴圈：

$i = 0;

until ($i == 10) {

print "$group$i\n";

$i++;

}

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

$i = 0;

do {

print "$group$i\n";

$i++;

} until ($i == 10);

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

map {print "$_\n"} @group; #每行列印 group 裡的一個元素

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

Perl 的應用

Perl 使用非常廣泛。在 Unix、GNU/Linux 和 macOS 中，Perl 是內建的系統指令碼工具。Perl 曾經在網頁中（PHP，CGI）廣泛使用。Perl 擁有海量的模組支援，在解決問題時，可以直接安裝使用，非常方便。截止 2025 年 2 月 2 日，CPAN 上釋出了大約 266,924 個 Perl 模組。

4.1 以 Perl 編寫的軟體

Bugzilla
Movable Type
Frozen Bubble

4.2 Perl Data Language

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

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

Perl 的社群文化

5.1 Perl 詩經

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

5.2 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 更好地支援面向物件，有專用於定義類的語法：

class Foo is Universal { # inherit form Universal

has $.member_variable

method member_function {print "some string";}

}

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

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

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

if $percent > 100 {say "weird mathematics";}

for 1..3 {

using $_ as loop variable

say 2 * $_;

}

for 1..3 -> $x {

with explicit loop variable

say 2 * $x;

}

while $stuff.iswrong {$stuff.trytomakeright;}

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

if ($hour> 22) { #正確

say'should sleep...';

}

if ($hour> 22) { #錯誤

say'should sleep...';

}