[Perl] 程式設計教學:基本觀念

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    前言

    本文介紹一些撰寫 Perl 程式相關的基本概念和工具。

    再訪 Hello World

    我們再看一次 Hello World:

    print "Hello World\n";
    

    Perl 和 C 或 Java 不同,沒有主函式 (main function) 的概念,執行某個命令稿時,該命令稿本身等同於主函式。

    print 是 Perl 的內建函式 (builtin functions),功能為在終端機輸出字串,由於 print 尾端不會自動加入換行符號,故需自行加入。內建函式是一些預寫好的 Perl 程式,只要呼叫該函式,即可立即獲得所需的功能。函式使用者不需在意這些函式內部的實作,只要將其視為一些立即可用的指令即可。

    在使用 Perl 函式時,可以省略括號,這時候函式看起來會很像 Perl 內建語法。Perl 刻意不嚴格區分函式和語法,雖然寫起來比較簡便,但有時也會造成混淆,所以筆者不建議使用 Perl 開發中大型程式。

    使用嚴格模式

    一開始在撰寫 Perl 命令稿時,會建議在命令稿的開頭加上以下 pragmas:

    use strict;
    use warnings;
    
    print "Hello World\n";
    

    Pragmas 是用來改變 Perl 的行為,以 use strict; 來說,會禁止一些過於鬆散的語法,而 use warnings; 會開啟較多的警告訊息。

    一開始練習撰寫 Perl 程式時,最好一律加上這兩個 pragmas,以免養成不良的撰碼習慣。等寫熟了之後,要寫一些用完即丟的命令稿或是 Perl one-liner 時,就不一定要加入這些 pragmas。

    Perl 的程式碼風格

    Perl 官方文件有建議的程式碼風格,可以讀一下,一開始完全沒學過 Perl 時可能無法吸收,可過一陣子再回頭看。

    O’Reilly 曾出過一本 Perl Best Practices (中譯已絕版),裡面有更多關於撰寫 Perl 程式的建議。這本書提供許多不錯的建議,但在某些面向主觀過強,不需照單全收。

    perlcritic 是一個以 Perl 寫成的 Perl 程式碼檢查軟體,會對 Perl 程式碼進行撰寫上的建議。在 perlcritic 程式中有實作一些來自 Perl Best Practices 的建議事項。

    重排 Perl 程式碼

    perltidy 是一個 Perl 程式碼重排工具,可以省下手動整理程式碼的工夫。該軟體有一些細項可以調整,有需要的讀者可自行閱讀其手冊。

    Perl 的文件

    Perl doc 網站收錄最新版本的 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 本身的文件。

    使用 Perl 撰寫命令列程式

    在類 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 命令稿

    前述的命令稿將 Perl 路徑寫死,可攜性較差。一般來說,我們會用 env(1) 工具自動判定 Perl 路徑,以改善可攜性:

    #!/usr/bin/env perl
    
    foreach my $a (@ARGV) {
        print "$a\n";
    }
    

    然而,使用 env 時,perl 指令後只能帶單一參數,這是 env 所帶來的限制。在 Perl 命令稿中,使用多參數的情形並不少見。我們可以用 shell 命令稿做為 wrapper 來改善這個問題:

    #!/bin/sh
    
    # Embed a Perl script in a shell script
    cat << 'SCRIPT' | perl - "$@"
    foreach my $a (@ARGV) {
        print "$a\n";
    }
    SCRIPT
    

    一開始系統會將該命令稿判定為 sh 命令稿,但我們在該命令稿中內嵌 (embedding) Perl 命令稿,再呼叫 perl 去執行該內嵌的命令稿。如果需要多個參數,將所需的參數直接寫入此命令稿即可。我們藉由 $@ 變數帶入外部的參數,所以該命令稿使用起來和一般的命令列工具無異。

    使用 shell wrapper 的缺點在於編輯器無法辨識內嵌的 Perl 命令稿,不會將該內嵌命令稿加上語法高亮,可維護性會略差一些。

    由於 Windows 系統沒有 env(1) 也不支援 sh(1),故無法使用本節所提到的技巧。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤新文章】
    Facebook Twitter Plurk