大家好:
以下是一篇由蕭永慶先生寫的介紹PERL這個語言的短文.此篇文章和另外一篇
王佑中先生所翻譯的PERL有關文件(中文postscript檔)皆可在以下的URL拿到:
ftp://ftp.math.ncu.edu.tw/chinese/DOC
當然! 請別忘了注意一下版權! :) 若有任何問題,除了聯絡作者外,也可聯絡
chenym@math.ncu.edu.tw 陳彥銘
##########################################################################
# 版權聲明 #
# #
# 本篇文章的版權為作者蕭永慶先生所有. 允許網路上的非營利轉載. #
# 作者的電子郵件地址:syc@cc.ntu.edu.tw #
# #
# 本文可在下列URL取得: #
# ftp://ftp.math.ncu.edu.tw/chinese/DOC/ #
##########################################################################
Perl 簡介 - $ID$
寫在前面: 有點懶懶的, 不太想用腦筋構思文章,想看的人就忍耐一下吧。
Perl是什麼東西呢? Manual上是這樣寫的: Practical Extraction and Report Language
它原始的目的就是用來取代UNIX原有的sed/awk 與shell script的組合, 用來
匯集資訊, 產生報表的一個工具語言(程式)。不過隨著版本的改進,功能越來
越強,現在的功能已經超乎原先設計時的想像,幾乎任何事都可以做到,也變
成每一部UNIX工作站必備的標準工具了。
Perl的作者是Larry Wall <lwall@netlabs.com>, 曾經貢獻過好幾個很有用的
程式給大家(public domain)使用,包括patch和rn。他設計perl時的哲學是以
實用為第一優先,(所謂的實用就是語言容易使用, 有效率, 而且完整),而不是設
計一個看起來很漂亮的語言。(漂亮就是程式非常的小,語法幽雅,而且只由
最少的語法基本元素構成)。Perl包含了C, sed, awk,和sh這幾個工具最好(作
者(Larry) 說的) 的特色,而且主要的語法很接近C 語言, 對原本熟悉C 語言
的人來說非常容易上手。
--------------------------------------------------------------------------
講完廢話,可以進入主題了。首先,我們按慣例用perl寫個程式印出Hello,World
吧。首先,用你自己最喜歡的編輯器建立hello這個檔案,如下:
#!/usr/local/bin/perl
#
# Program 'hello': print out 'Hello, World' on standard out.
#
print "Hello, World" ;
# end of file
前面幾個以 #號開頭的行在UNIX的習慣裡面是註釋,所以實際上的程式
只有一行而已。不要忘掉print 那一行最後的那個分號。還有要注意perl
會區分大小寫。
不過這裡有個小細節要注意,就是第一行:
#!/usr/local/bin/perl
乍看之下是註釋,其實它大有作用。在古早的UNIX系統裡面,可執行檔分作兩種,
一種是包含機器指令的二進位檔,系統可以直接載入執行;另外一種叫做
script檔,也就是包含一些shell命令的普通文字檔:UNIX一遇到這種文字檔
就會自動載入/bin/sh去解譯與執行它。不過隨著UNIX的發展,shell越來越多,
實在不曉得script檔是用哪種shell寫的。所以就發展出一個機制,在每個script
檔的第一行(前面不可以有空白與空白行)寫個#! ,然後接著寫真正要負責處理這個
script的程式檔路徑,就可以讓UNIX知道要用那個程式來處理了。另外,順便囉唆一下,
這個路徑後面還可以再加一個參數(one and only one),如下:
#!/usr/local/bin/perl -f 對
#!/usr/local/bin/perl -pi.bak 對
#!perl -f -pi.bak 不對 -> -pi.bak會被忽略。
反正寫超過一個就會被忽略就對了。
好了,回歸主題,要如何執行這個程式呢? 有好幾個方法:
1. 直接在命令列打: (venus% 是我們shell的提示號,不用輸入)
venus% perl hello
2. 讓perl從standard input讀入perl程式:
venus% perl < hello
3. 把hello改成可執行檔,然後再執行:
venus% chmod a+x hello
venus% ./hello
註1: 如果你的 $PATH (或 $path in csh)有 "." (目前目錄)的話
就可以不用打 "./" 。
註2: 你必須確定perl是放在/usr/local/bin/perl上,不然的話
請把這個字串改到正確的值(可能是/bin/perl, 試不出來問root)。
哇!好不容易可以執行第一個程式了。結果應該就是我們期望的Hello, World了。
第二個執行的方法蠻有趣的,換句話說,你可以這樣子輸入perl程式:
venus% perl (直接按ENTER)
print "Hello,World\n" ;
CTRL-D
CTRL-D就是UNIX的end of file,perl處理命令的時候會整個檔案都讀入、
分析一遍後,再開始執行,所以Hello,World會在按完CTRL-D後才印出來,
而不是打print ...;之後就立刻印出。
--------------------------------------------------------------------------
囉唆完一些背景知識後,我們可以把注意力全部集中在perl本身了。首先是
perl支援的變數型態。perl下的變數型態總共有三種: scalars (純量), arrays
of scalars (純量陣列), associative arrays (相關陣列?實在不會翻,看下
面的註解好了)。
Arrays (of scalars) 與Associative arrays的差別:
"一般所謂的arrays是一塊連續的記憶體,它的每一個元素的大小都是一樣的,
可以很快的透過數字(第幾號元素)利用CPU 本身的定址能力直接取出來;
而associative arrays比較像一張對照表,給定一個值(有可能是一個字串),
要先在這張表內搜尋,找到這個『鍵』,然後才能找到相對應的值出來。
差別就是arrays (of scalars)速度比較快, associative arrays通常都是
利用一些資料結構達成的,比較慢, 不過比較有彈性就是了。"
perl的變數不需要事先宣告,直接就可以用了。
變數以$ 開頭, 以下是幾個例子: (每一行都是獨立互不相干的)
$days # a simple scalar variable
$days[28] # 29th element of array @days
$days{'Feb'} # one value from an associative array
$#days # last index of array @days
一整個(或者是部份的)array用@表示:
@days # ($days[0], $days[1], $days[2], ...$days[n])
@days[3,4,5] # same as @days[3..5] 等於 ($days[3],$days[4],$days[5])
@days{'a','c'} # ($days{'a'}, $days{'c'})
一整個assosiative array用%開頭:
%days # (key1, val1, key2, val2, ....)
對於每一種資料型態, 他們的命名空間是互相獨立而不受干擾的, 也就是說,
$days, @days, %days這三個符號可以同時存在而互不影響。
以上這八種表示法都可以作為lvalue, 換句話說, 都可以放在等號的左邊,
可以設值。如下:
$d = 20;
$a[18]=1;
$days{'Feb'} =28;
@arr = ('a','b','c','d','e');
@days[3,4,5] = ( 1, 2, 3 );
@days{'a','c'} = ('Monday','Wednesday');
甚至: ($s1,$s2,$s3) = $Bar(2,3,4);
ps: 前面沒有提到, 不過應該很簡單, 就是常數array就是用小括號括起來形成一個
"list"就對了。字串就是用單引號或雙引號括起來。詳情見後面說明。
Array @classes 的大小可以由$#classes的值得到。(實際上是array長度減一,
因為$#classes是@classes最後一個元素的索引(index),而通常array都是從0開始
算的)。 要改變array的大小就直接改$#classes就好了。不過縮小array並不會
真的把array的資料丟掉, $#array改大後又可以取回來了。把array刪掉的方法是
@array = ();
$#array = $[ -1; (兩者同義, $[是特殊變數, 表示array的基數,
就是說array是由$[開始算的; array的第一個元素.
通常$[ == 0 )
另外, 如果把array當作scalar(純量)用的話, array會傳回該array的長度。
scalar(@array) 等於 $#array - $[ + 1 (末項 - 前項 + 1 = 長度)
如: $len = @array;
perl沒有提供多維陣列, 但是有提供一些機制來利用associative array模擬
多維陣列。例:
$foo{ $a,$b,$c } = 1; (等於 $foo{ "$a,$b,$c" } = 1;)
最後, 如果一個變數名稱用特殊符號開頭,那該名稱就只能該符號有一個字元, 如
$;
$$
$%
等。而且這些變數通常都有一些特別的意義。
常數的使用就像一般一樣:
12345
12345.67
3.1428E-10
0xffff #十六進位
0377 #八進位
4_294_976_296 # 429976296
字串常數則用單引號或雙引號括起來。他們的效力與shell下一樣: 雙引號括起來的字串
仍然會做變數和反斜線替換,而單引號不會(除了\'與\\)。如:
$h = "Hello";
$w = "World";
$hw = "$h,$w"; # Hello,World
print "Item1\tItem2\n"; "Item1<TAB>Item2<NewLine>"
反斜線替換常用的和C一樣,詳情請看perl manpage.
--
在年輕的飛奔裡
你是迎面而來的風
--
※ 發信站: 批踢踢實業坊(ptt.twbbs.org)
◆ From: h153.s95.ts30.h