Friday, March 11, 2011

讓 Perl 走進你的生活

本文是用來回顧剛接觸 Perl 的心得,以及推薦新手跳入 Perl 所寫的。

從 1987 年 Larry Wall 發明 Perl 以來,今年 Perl 已經24 歲,可能比你我還年輕,不過以電腦語言的角度來看算是老了。筆者在多年前就已經接觸過 Perl,可惜當時覺得程式艱澀難懂,不如 C 來的直接。直到最近因工作需要重新學習,才發覺過往的偏見。

借用 Alan Perlis 的話: "A language that doesn't affect the way you think about programming, is not worth knowing." (若是一種語言不會影響你對寫程式的想法,那便不值得學習。)
而讓我改變對寫程式的想法的,便是 Learning Perl 這本書。

Learning Perl的作者 Randal L. Schwartz (以下簡稱 Randal)在書的第一章就指出,Perl是非常高階的語言,所以code的密度很高,長度只有相對應的C的四分之一到四分之三。我認為用一個中文字來表現Perl的編程精神就是""。短程式的好處不少,不論是閱讀時間或是寫程式的時間都比較短。這就像是自然語言中的成語,可以把一段故事濃縮成寥寥數字。

借用 Randal 第一章的程式碼來說明


while (<>) {
  chomp;
  print join("\t", (split /:/)[0, 2, 1, 5] ), "\n";
}

希望第一次看到 Perl 的朋友不要轉頭離開。
任何程式語言的目的都是為了幫助使用者解決問題,而不是折磨使用者。
這段Perl程式目的是: 依序讀取命令列中每個檔案的每一行,去除尾部的換行符號厚,依冒號分隔欄位,並列印出其中四個欄位的值。假設我們有下的檔案 data.txt:

Id:Name:Age:Gender:Height:Weight

001:John:20:Male:180:70
002:Alice:17:Female:160:50



當我們在命令列下這樣的指令時:

> perl program.pl data.txt

結果會是:

Id      Age     Name    Weight
001     20      John    70
002     17      Alice   50


如果你看到這裡,一定會想知道這段程式要怎麼解析,<>是甚麼? chomp是甚麼? join 和 split 是甚麼?
在此筆者不會做完整解釋,請隨著 Randal 一同進入 Perl 的世界即可,那過程會比我現在說明得更加有趣數十倍。不過我想帶給各位Perl這種所謂"高階"程式的精神,就是要符合使用者的自然習慣。我們可以用一種很不嚴謹的角度來看剛才這段程式。首先我們想要一行一行處理資料,所以就需要一個 while 迴圈,由於我們要從命令列指定的檔案讀出資料,這整件事就用一個名詞 <> 來表示,讀到一行資料以後要用冒號分隔,所以就使用 split。

至於讀者可能會問說,那讀入的資料是暫存在哪個變數呢? Perl認為這是可以省略的變數,所以動了一些手腳。就好比我們在日常生活中,你拿起一個裝水的杯子,下一個動作是喝水,你不需要再多說明我是從手上的杯子喝水的。

最後結尾放上 Learning Perl 這本書的封面,各位請不要拿錯了呀 :)