前言
本文假定讀者沒有寫過 Perl 程式或僅寫過少量 Perl 程式,從頭介紹一些撰寫 Perl 程式相關的基本概念和工具,讓讀者可以開始撰寫 Perl 程式。
副檔名 (File Extension)
- 獨立的 Perl 命令稿以 .pl 為副檔名
- Perl 模組則以 .pm 為副檔名
- Perl 延伸模組則以 .xs 為副檔名
- 只有文件的 Perl 命令稿會用 .pod 為副檔名
- 測試程式會以 .t 為副檔名
把 Perl 命令稿當成 Unix 指令時,不需要副檔名,只要記得開啟「可執行」即可。
執行 Perl 程式的方式
Perl 程式有兩種執行方式:
- 撰寫 Perl 命令稿後,執行該命令稿
- 從命令列直接執行 Perl 程式 (即 Perl one-liner)
第一種方式是大部分高階直譯語言都會採用的方式,但第二種方式則相對少見,由於 Perl 兩者兼具,故筆者認為 Perl 做為一個命令列工具仍然有其一定的價值。
在本文中,我們會用這兩種方式各寫一個 Hello World 程式,以熟悉撰寫 Perl 程式的方式。
使用命令稿寫 Hello World 程式
Hello World 程式是用來熟悉開發流程的經典範例,原見於經典的 The C Programming Language ,此處撰寫 Perl 的版本。
Windows
使用編輯器撰寫 hello.pl 程式,加入以下程式碼:
print "Hello World", "\n";
不用在意程式碼的細節,我們只是要確認程式可執行。
使用以下指令來執行該命令稿:
> perl hello.pl
Hello World
若出現 Hello World 訊息,代表程式執行成功;若沒有執行成功,需自行根據錯誤訊息來除錯。
Unix
如果讀者使用 Unix,可以把 Perl 命令稿製作成命令列程式。略為修改一下 hello.pl 的內容:
#!/usr/bin/perl
print "Hello World", "\n";
我們額外加入的一行稱為 shebang。對 Perl 來說,該行只是註解 (comment)。但 Unix 會根據該行的內容啟動指定的直譯器 (interpreter)。以本例來說,就是啟動 Perl。
把該命令稿加上可執行權限:
$ chmod +x hello.pl
執行該命令稿:
$ ./hello.pl
Hello World
這裡有用到 Unix 的特性,在 Windows 上則無法使用這個方法。
在命令列即時撰寫 Hello World 程式
以下是直接使用命令列撰寫 Hello World 程式的版本:
$ perl -e 'print "Hello World\n";'
Hello World
在 Windows 則要稍微修改一下:
> perl -e "print \"Hello World\n\";"
Hello World
這是因為命令提示字元的字串只能用雙引號括起來的緣故,所以在 Windows 寫 Perl 單行程式會稍微麻煩一點。
Perl 單行程式有許多使用方式,國外也出過一些相關的專書。Perl 單行程式主要是在命令列上即時輸入一些短小的 Perl 程式,如果發現 Perl 單行程式可能會很長時,最好就轉成命令稿的形式來寫。
再訪 Hello World
我們再看一次 Hello World:
print "Hello World", "\n";
Perl 和 C 或 Java 不同,沒有主函式 (main function) 的概念,執行某個命令稿時,該命令稿本身等同於主函式。
print 是 Perl 的內建函式 (builtin functions),功能為在終端機輸出字串,由於 print 尾端不會自動加入換行符號,故需自行加入。
內建函式是一些預寫好的 Perl 程式,只要呼叫該函式,即可立即獲得所需的功能。函式使用者不需在意這些函式內部的實作,只要將其視為一些立即可用的指令即可。
在使用 Perl 函式時,可以省略括號,這時候函式看起來會很像內建語法。
Perl 刻意不嚴格區分函式和語法。雖然寫起來比較簡便,但有時也會造成混淆,所以筆者不建議使用 Perl 開發中大型程式。
使用嚴格模式
一開始在撰寫 Perl 命令稿時,會建議在命令稿的開頭加上以下 pragma (編譯指示):
use strict;
use warnings;
Pragma 用來改變 Perl 的行為。以 use strict; 來說,會禁止一些過於鬆散的語法,而 use warnings; 會開啟較多的警告訊息。
一開始練習撰寫 Perl 程式時,最好一律加上這兩個 pragma,以免養成不良的撰碼習慣。等寫熟了之後,要寫一些用完即丟的命令稿或是 Perl 單行程式時,就不一定要加入這些 pragma。
程式碼風格 (Coding Style)
Perl 官方文件有建議的程式碼風格,可以讀一下。一開始完全沒學過 Perl 時可能無法吸收,可過一陣子再回頭看。
O'Reilly 曾出過一本 Perl Best Practices (中譯已絕版),裡面有更多關於撰寫 Perl 程式的建議。這本書提供許多不錯的建議,但在某些面向主觀過強,不需照單全收。
perlcritic 是一個以 Perl 寫成的 Perl 程式碼檢查軟體,會對 Perl 程式碼進行撰寫上的建議。在 perlcritic 程式中有實作一些來自 Perl Best Practices 的建議事項。
重排程式碼 (Reformatting)
perltidy 是一個 Perl 程式碼重排工具,可以省下手動整理程式碼的工夫。該軟體有一些細項可以調整,有需要的讀者可自行閱讀其手冊。
Perl 文件 (Documentation)
Perldoc 網站收錄最新版本的 Perl 的官方文件。對於 Perl 學習者來說,應該要習慣去查閱這個網站的內容。
除了使用該網站外,perldoc 是一個隨 Perl 發佈的命令列工具,其用途是在本地端查詢 Perl 文件。
使用 perldoc -f 可以查詢 Perl 內建函式 (built-in function) 的用法:
$ perldoc -f sprintf
使用 perldoc -v 可以查詢 Perl 內建變數 (built-in variable) 的用法:
$ perldoc -v '$"'
查詢 Perl 內建變數算是蠻實用的功能。因為許多 Perl 內建變數是以非文字符號的方式來表示,使用一般的搜尋引擎不易搜尋。
perldoc 也可查詢模組名稱:
$ perldoc Moo
至於其他的用法,請閱讀 perldoc 本身的文件。
撰寫命令列程式
在類 Unix 系統上,在命令稿的最開頭使用 #! (shebang) 可以讓命令稿變成命令列工具。例如以下的命令稿:
#!/usr/bin/perl
print "Hello World", "\n";
在本例中,該命令稿藉由 shebang 提示系統,使用位於 /usr/bin/perl 的執行檔執行本命令稿。
只要給予該命令稿可執行 (executable) 的權限即可執行此命令稿:
$ chmod +x hello.pl
$ ./hello.pl
Hello World
Unix 的終端機環境不以副檔名判斷程式,連 .pl 都可以省略,這樣該命令稿看起來就和其他命令列工具無異。
由於 Windows 系統沒有 shebang 的特性,這個方法在 Windows 上無效。
在 Windows 上的 Perl (和其他直譯語言) 命令稿還是要保留副檔名較好,因為 Windows 需要用副檔名來判斷檔案的執行方式。
撰寫具備可攜性的 Perl 腳本
使用 env(現代標準做法)
一般而言,建議使用 env(1) 工具來自動搜尋並判定 Perl 的安裝路徑,以提升腳本跨平台的建置能力(可攜性):
#!/usr/bin/env perl
對絕大多數現代 Unix/Linux 系統來說,這是最通用且符合直覺的標準寫法。
早期系統的特殊過渡寫法
在少數極其古老的 Unix 系統中,為了繞過 Shebang (#!) 的字數限制或照顧特定編輯器,會採用以下方式來啟動 Perl:
#!/bin/sh
#! -*- perl -*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
if 0;
現代開發環境已不再需要這種複雜的包裝,此寫法目前僅供歷史參考。
將 Perl 內嵌於 Shell 腳本中
使用 env 宣告時,perl 指令後方通常只能承接單一參數,這是 env 本身的系統限制。若你的 Perl 腳本需要同時帶入多個直譯器參數(例如 -w -s),可以使用 Shell 腳本(Wrapper)將其封裝:
#!/bin/sh
# Embed a Perl script in a shell script
cat << 'SCRIPT' | perl - "$@"
foreach my $a (@ARGV) {
print "$a\n";
}
SCRIPT
系統啟動時會先將此檔案判定為 Sh 腳本,接著透過進程管道將內嵌的 Perl 原始碼傳送給 perl 解譯器執行。
這種做法能完美透過 $@ 變數將外部參數傳入,使其操作體驗與一般命令列工具無異。不過其缺點在於,多數文字編輯器無法辨識 Shell 檔案內嵌的 Perl 程式碼,因此無法提供語法高亮(Syntax Highlighting),在後續維護上會稍微吃力。
Windows 環境限制
由於 Windows 系統原生不內建 env(1) 亦不支援 sh(1),因此本節所提及的 Shell 包裝與路徑自動偵測技巧,在 Windows 環境下皆無法直接適用。
線上執行 Perl 程式
以下是一些可透過瀏覽器執行 Perl 程式的線上平台:
這些平台當然無法取代真正的開發環境,但可用在學習 Perl 基本語法。