Perl學習資料

網站:

https://www.perl.org/

http://zh.wikipedia.org/zh/Perl


書籍:《learning perl》

http://learn.perl.org/

http://www.perl6.org/

http://www.perl6.org/archive/



簡介:

Perl高階、通用、直譯式動態的程式語言。最初設計者拉里·沃爾Larry Wall)為了讓在UNIX上進行報表處理的工作變得更方便,決定開發一個通用的腳本語言,而在1987年12月18日發表。目前,版本中包含Perl 5以及Perl 6(開發中)。

Perl借用了Csedawkshell腳本以及很多其他程式語言的特性。其中最重要的特性是Perl內部集成了正則表達式的功能,以及巨大的第三方代碼庫CPAN

2000年開始,目前拉里·沃爾開始開發Perl 6,來作為Perl的後繼;不過,Perl 6語言的語法有很多轉變,所以Perl 6被視為Perl家族中的另一個語言。[2]

Perl語言的應用範圍很廣,除CGI以外,Perl被用於圖形編程、系統管理、網絡編程、金融、生物以及其他領域。由於其靈活性,Perl被稱爲腳本語言中的瑞士軍刀。


駱駝標誌[編輯]

駱駝標誌

Programming Perl》,由奧萊理媒體發佈,特色是封面有一張駱駝的圖片,因而被稱作“駱駝書”[28]。這張駱駝的圖片已經成爲了Perl非官方的標誌和一個黑客的標誌,這出現在T恤衫和其它衣服上。

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

洋蔥標誌[編輯]

洋蔥標誌

Perl基金會擁有一個可選的標誌,一個洋蔥,允許它的子站點,Perl MongersPerlMonks,Perl.org和其它網站使用[32]

Perl簡介[編輯]


Perl語言的中心思想[編輯]

Perl語言的中心思想可以集成爲一句話「TMTOWTDI」:

There's More Than One Way To Do It.
(不只一種方法來做一件事。)

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

There's more than one way to do it, but sometimes consistency is not a bad thing either.
(不只一種方法來做一件事,但有時保持一致也不錯。)

  • TIMTOWTDIBSCINABTE,發音爲“Tim Toady Bicarbonate”[33].

另一個Perl程序員常常想起的Perl俗語是:

Easy things should be easy, and hard things should be possible.
(簡單的事情應該是簡單的,複雜的事情應該變得可能。)

優點[編輯]

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

由於從其他語言大量借鑑了語法,使得從其他編程語言轉到Perl語言的程序員可以迅速上手寫程序並完成任務,這使得Perl語言是一門容易用的語言。

缺點[編輯]

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

同樣的,因爲Perl這樣隨意的特點,可能會導致一些Perl程序員遺忘語法,以至於不得不經常查看Perl手冊。對此,《Learning Perl》一書裏建議經常使用Perl編程。

建議的解決方法是在程序裡使用use strict;以及use warnings;,並統一代碼風格,使用庫,而不是自己使用「硬編碼」。Perl同樣可以將代碼書寫得像PythonRuby等語言一樣優雅。

Perl的語法[編輯]

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!”,以及一個換行。

變量[編輯]

Perl是一種無類型語言(untyped),換句話說,在語言層面上,Perl和大多數編程語言不同,不把變量分成整數字符浮點數等等,而只有一種能接受各種類型數據的“無類型”變量。Perl的變量以$字符開頭。例如$a=5;$b="Hello";$c=3.2;$d='\n這裏並不換行'都是合法的Perl語句。

Perl中各種變量的運算也很自由,數和含有數的字符串是等效的,可以把數字字符串參與數學計算,也可以反之,讓數字參與字符串的構成和操作。

除單個變量(Perl稱爲標量「Scalar」)之外,Perl還有兩種集合類型,分別是數組(Array,用@字符開頭)和關聯數組(Associative array,或者稱爲Hash,用%開頭。類似C++0xSTL 無序表「unordered_map」和Python的字典「Dictionary」)。數組可以內含任意可變數目的變量,並以其存儲順序作爲索引以完成常數時間的定位;而Hash表,則可以在變量之間建立一一映射,就像字典一樣,把不同的變量按照他們的邏輯關係組織起來,並以作爲“鍵”的變量進行索引,完成常數時間的定位。

另外,Perl還有一種特殊的類型,引用(reference),類似於指針,當作標量處理,可以指向標量(含引用)、數組、Hash等任何類型。如:

$foo = \$bar; print $$foo;
$foo = \@bar; print @$foo;
$foo = \%bar; print %$foo;
$foo = \&bar; print $foo->(); print &$foo;

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

sub foo
{
    my $var = shift;
    $$var = '1';
}
my $foo = '2';
my $var = \$foo;
print $$var;
foo ($var);
print $foo;

輸出“21”,即foo()內改變了$foo。

判斷語句[編輯]

因爲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'; } #只可以寫成區塊。
}

由於邏輯運算元的作用,還可以寫出不用關鍵字ifunless的判斷語句,如常用的打開文件語句:

open DATA, '<', $filename or die "Can't open $filename: $!\n";

循環語句[編輯]

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 < 10; $i++) {
    print "$group[$i]\n";
}

while循環:

$i=0;
while ($i < 10) {
    print "$group[$i]\n";
    $i++;
}

do...while循環:

$i = 0;
do {
    print "$group[$i]\n";
    $i++;
} while ($i < 10);

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;

其實還有其他的循環方式。總而言之,就是TMTOWTDI

函數[編輯]

Perl提供了可以直接調用的、數目衆多的函數。可以對以下對象進行操作:

  • 數組:chomp, join, keys, map, pop, push, reverse, shift, sort, splice, split, unshift, values
  • 數據庫:dbmclose, dbmopen
  • 目錄:chdir, closedir, mkdir, opendir, readdir, rewinddir, rmdir, seekdir, telldir
  • 文件:binmode, chdir, chmod, chown, chroot, close, eof, fnctl, fileno, flock, getc, glob, ioctl, link, lstat, open, print, printf, read, readdir, readlink, rename, rmdir, seek, select, stat, symlink, sysopen, sysread, syswrite, tell, truncate, umask, unlink, utime, write
  • 組:endgrent, getgrent, getgrgid, getgrname, getpgrp, setgrent, setpgrp
  • Hash: delete, each, exists, keys, values
  • 主機:endhostent, gethostbyaddr, gethostbyname, sethostent
  • 輸入:getc, read, sysread
  • 處理器間通訊:msgctl, msgget, msgrcv, msgsnd, pipe, semctl, semget, semop, shmctl, shmget, hmread, shmwrite
  • 數學:abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand
  • 消息隊列:msgctl, msgget, msgrcv, msgsnd
  • 其他:bless, defined, do, eval, formline, import, ref, scalar, syscall, tie, tied, undef, untie, wantarray
  • 網絡:endnetent, getnetbyaddr, getnetbyname, getnetent, setnetent
  • 輸出:die, print, printf, syswrite, warn, write
  • 口令:endpwent, getpwent, getpwname, getpwuid, setpwent
  • 進程:alarm, die, dump, exec, exit, fork, getlogin, getpgrp, getppid, getpriority, kill, setpriority, sleep, system, times, umask, wait, waitpid
  • 協議:endprotent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, setprotoent
  • 正則表達式:grep, pos, quotemeta, reset, split, study
  • 範圍:caller, local, my
  • 服務:endservent, getservbyname, getservbyport, getservent, setservent
  • 套接字:accept, bind, connect, gethostbyaddr, gethostbyname, gethostent, getpeername, getservbyname, getservbyport, getservent, getsockname, getsockopt, listen, recv, select, send, setsockopt, shutdown, socket, socketpair
  • 字符串:chop, chr, crypt, hex, index, join, lc, lcfirst, length, oct, Ord, pack, q, qq, quotemeta, qw, qx, reverse, rindex, split, sprintf, substr, uc, ucfirst, unpack, vec
  • 時間:gmtime, localtime, time
  • UNIX: chmod, chown, chroot, dump, endgrent, endhostent, endnetent, endprotent, endpwent, endservent, fnctl, fork, getgrent, getgrgid, getgrname, gethostent, getlogin, getnetent, getpgrp, getppid, getpriority, getprotobyname, getprotobynumber, getprotoent, getpwent, getpwname, getpwuid, getservbyname, getservbyport, getservent, ioctl, link, lstat, readlink, select, setgrent, sethostent, setnetent, setpgrp, setpriority, setprotoent, setpwent, setservent, sleep, syscall, times, umask, wait, waitpid

perlfunc(1)裏可以按字母序查找Perl函數用法。

Perl的應用[編輯]

Perl主要應用在Unix平臺和網頁中(PHPCGI)。Perl擁有海量的模塊支持,在解決問題時非常方便。CPAN有很多Perl模塊。

Perl Data Language[編輯]

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

而且PDL提供了與很多其他軟件包的接口,例如FFTW(一個快速傅立葉變換的軟件包),又或者是MesaLinux上的OpenGL三維圖形渲染包),這些包原來往往僅提供C/C++語言接口。這一功能使PDL成爲拓展Perl功能的一箇中間層。

Perl詩經[編輯]

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

另一個Perl黑客的有趣活動是寫JAPHs

以Perl編寫的軟件[編輯]

競爭對手[編輯]

因為許多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的後繼者。[35]

Perl 6[編輯]

Camelia,Perl 6項目的標誌[36]

Perl 6正在開發中,它將會與現在的Perl版本有很大不同,但相信還要開發一段長時間。 其中最主要的改變是,Perl 6會是完全物件導向的,有專用於宣告類別的語法:

class Foo is Universal { # inherit form Universal
    has $member_variable
 
    method member_function {
        print "some string";
    }
}

而且可以給變量定義類型,當類型不匹配時,就會報錯[37]

另外,Perl 6提供了不同的正則語法,新的語法稱作「規則」,並且允許使用者在正則中加入空格等以便閱讀,也可以命名一個正則方便調用[38]

Perl 6中的控制流程和循環的判斷條件的括號是可選的,如:

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.is_wrong {
    $stuff.try_to_make_right;
}

但是如果加入括號,不能緊跟在關鍵字後邊,而要空一格,因為像foo()這樣的形式,會調用函數,而不管它是不是關鍵字[39]

if ($hour > 22) { #正確
    say 'should sleep...';
}
if($hour > 22) { #錯誤
    say 'should sleep...';
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章