Perl

求闻百科,共笔求闻
Perl
编程范型多重编程范式函数指令式面向对象 (基于类编程)、反射过程式事件驱动泛型
设计者拉里·沃尔
实作者拉里·沃尔
发行时间1987年12月18日,​36年前​(1987-12-18
稳定版本
5.38.0
型态系统动态
实作语言C语言
操作系统跨平台
许可证艺术许可协议 1.0[1][2]
GNU通用公共许可证[3]
文件扩展名.pl, .pm, .t, .pod
网站www.perl.org
受启发于
AWKC语言C++LispPascal, sedSmalltalk 80Unix shell
施影响于
CoffeeScriptECMAScriptGroovy
JavaScriptJuliaLPCPerl 6(Raku)、PHPPythonRubyWindows PowerShell

Perl是一门通用高级解释型脚本语言。由拉里·沃尔草创于1987年,它主要被用做 Unix 系统管理,在历史上也曾是CGI编程的主流语言。Perl 的语言设计融合了sed,awk,C,Shell等诸多语言的特性。Perl 最突出的特性是它强大的内置正则表达式库。同时,其第三方代码库CPAN包含数量庞大的包。

2000 年起,由拉里·沃尔主导开发了Perl6语言以期作为Perl5的后继,但开发极为缓慢且不稳定。最终,于2015年,Perl6正式更名为 Raku,成为 Perl 语言家族的一个成员[4]

历史

版本[5] 最后更新于[6]
旧版本,不再支援: 5.4 1999-04-29
旧版本,不再支援: 5.5 2004-02-23
旧版本,不再支援: 5.6 2003-11-15
旧版本,不再支援: 5.8 2008-12-14
旧版本,不再支援: 5.10 2009-08-22
旧版本,不再支援: 5.12 2012-11-10
旧版本,不再支援: 5.14 2013-03-10
旧版本,不再支援: 5.16 2013-03-11
旧版本,不再支援: 5.18 2014-10-01
旧版本,不再支援: 5.20 2015-09-12
旧版本,不再支援: 5.22 2017-07-15
旧版本,不再支援: 5.24 2018-04-14
旧版本,不再支援: 5.26 2018-11-29
旧版本,不再支援: 5.28 2020-06-01
旧版本,不再支援: 5.30 2020-06-01
旧版本,不再支援: 5.32 2021-01-23
旧版本,不再支援: 5.34 2022-03-13
旧版本,仍被支援: 5.36 2023-04-23
当前版本: 5.38 2023-07-02
格式:
旧版本
旧版本,仍被支援
当前版本
最新预览版本
未来版本

Perl 5 以前

Perl 由 Larry Wall 创建于 1987 年。当时在Unisys程序员[7]的沃尔于 1987 年 12 月 18 日在comp.sources.misc新闻组发布了 Perl 1.0[8]。沃尔最早给这个语言取的名字是“Pearl”(意为珍珠),然而另一门语言PEARL早已存在,为了防止混淆,沃尔才把它改名Perl[9]

Perl 2 于1988年发布,引入了许多现在习以为常的功能,例如函数的递归调用,同时其正则表达式引擎被完全重写。

Perl 3 于1989年发布,添加了对二进制数据流的支持。

早期Perl唯一的文档是一个随新功能的加入而逐渐变长的手册页。1991年,《Programming Perl》(因封面是一头骆驼而常被称作“骆驼书”)出版了。为了和这本书匹配,Perl 的版本号被改为了 4,但并无实质改变。同时,Perl 4 引入了 Artistic License。从此 Perl 同时在 Artistic License 和 GPL 下许可[9]

Perl 5

Perl 5 是目前 Perl 语言最主流的版本。和 Perl 4 相比,Perl 5 几乎完全重写了解释器,引入了对象和面向对象系统,一套完善的文档体系(perldoc 查看器和 POD 文档格式),词法作用域(先前版本只有动态作用域[9][5]

早期 Perl 5 的发行时间不规律,在 Perl 5.6 后,Perl 版本号改为和大多数软件相同的 major.minor.patch 格式;在 Perl 5.8 后,Perl 的更新频率才稳定在每年一次更新。现今 Perl 版本号遵循以下规则:若 minor 版本为奇数则为开发版本,否则为正式发布的版本。

Perl 5 之后

2000 年的 Perl 大会上,拉里·沃尔在他的State of the Onion演讲中第一次提出了开发新版本 Perl 的设想[10][11]。当时的设想是移除当时 Perl 语言的历史包袱。随后,进行了 RFC 征集活动来确定该语言的设计[12]

此后 Perl 6 的开发进行一直十分缓慢,直到 2015 年才发布了第一个稳定版本[13]。由于 Perl 6 被设计为不向后兼容 Perl 5,该语言最终被重命名为 Raku,成了 Perl 语言家族的一个成员[4]。两门语言现在独立开发,并自由地从对方那里汲取灵感[14]

应用

传统上,Perl主要应用在Unix平台系统管理和网络编程中(主要是使用CGI)。Perl拥有良好的模块化支持,也有着成熟的模块仓库(CPAN),因此在解决实际问题时非常方便。

尽管CGI曾经是Perl网络编程的主流方式,但是现在一般已经认为它是过时的技术。CGI相关模块(CGI.pm)也已经被从Perl标准分发版中移除[15][16]。目前,Mojolicious,Catalyst,Dancer2等是Perl网络编程的主流库。

同时,由于 Perl 拥有强大的正则表达式和文字处理能力,在生物信息学等领域中也有广泛的应用。

设计

Perl 的中心思想是“有不止一种方法做这件事”(There Is More Than One Way to Do It, TIMTOWDY)。Perl 的语法借鉴了诸多语言,使得它拥有很多冗余语法。Perl最根本的编程范式面向过程[17]。与很多高级语言相同,Perl 中有着变量、表达式、函数和函数调用、赋值、控制结构等概念。一个Perl程序本质上是从上到下执行的一串定义或语句[18]。Perl 使用花括号来定义语句块,因此它的语法与 C 语言较为相近。

类型系统

Perl将类型分为标量(scalar),标量列表(array of scalar)和标量的哈希(hash of scalar),其中后两者是标量的集合(即以某种方式存储多个标量)。存放它们的变量分别使用 $, @, % 前缀。

Perl 中的标量可以是数字,字符串或引用。与许多高级语言不同,Perl本身并不提供直接将变量定义为数字等具体类型的方法。换句话说Perl的标量是无类型(untyped)的。标量的前缀标志是$符号。Perl的类型系统较弱,数字类型可以和字符串类型之间进行运算。

引用是 Perl 中较为特殊的一种类型。引用类似于 C 语言中的指针,可以指向某个其他变量。利用引用可以实现嵌套的数据结构(例如哈希的列表,列表的哈希等)。

集合类型是以某种方式存储多个标量的结构。Perl 提供了两种集合类型:列表(array)和哈希(hash),其中前者提供了顺序存储标量的功能,后者提供了以键值对形式存储标量的功能(类似其他语言中的关系数组字典)。集合类型内存储的只能是标量,如果需要嵌套集合类型,必须使用引用。

上下文是 Perl 为解决动态类型和弱类型导致的歧义性的工具。在 Perl 中上下文一词有两个含义:在进行运算时,每个类型有自己的上下文 [19],而在调用函数或使用某些运算符时,函数也可获知自己被调用的上下文,并根据它来决定做什么操作。函数调用共有空(void),标量(scalar)和列表(list)三个上下文,内置函数wantarray可以告诉某个函数在哪个上下文中。上下文可以使函数按照所需要的内容返回恰当的内容。

语法

参见:C语言

Perl的语法大多与C语言相似或相同。但在C语言提供的控制结构之外,Perl提供了一些语法糖。例如,unless 在条件不为真时执行语句块,而until在条件不为真时循环执行语句块[18]

Perl 缺少大多数类 C 语言中有的多分支选择语句(switch 语句),Raku 中引入了功能上相似但有本质不同的given...when...语句,并被 Perl 借鉴。但 Perl 5.36 之后它已不再是默认打开的功能。

面向对象

Perl使用基于类的面向对象,所有对象都有一个类。但和大多数此类语言不同,Perl在很长时间内都不提供class等直接定义类的语法结构。相反,Perl要求用户“保佑”(bless)一个普通变量(通常是哈希,也可以是其他类型的变量),此后这个变量就被视作一个对象,而这个变量所属于的包(package)则被视作它的类。可被用于定义它的行为。

由于Perl的对象系统并不实用,大多数人不直接使用它提供的功能而使用一些封装的库。CPAN上的Moose是最为常用的面向对象封装库之一[20]

自Perl 5.38起[21],Perl 提供了class关键字和一系列其他关键字,来实现和主流语言类似的面向对象功能。class并不是对bless的封装[22],而是一套独立的,内置于Perl解释器中的对象系统。

社群与文化

CPAN

创建于1993年[9]的CPAN是一个用于中心化管理Perl模块的仓库。CPAN的运营模式参照了TeXCTAN[23]。CPAN上有超过215,060个模块[24]。可以用命令行工具cpan来管理这些模块[24]

Perl 文化

Just another Perl hacker(另一个Perl黑客)是一个和国际C语言混乱代码大赛有着相同精神的社区文化。Perl程序员通过使用各种非传统方法写JAPH代码(能输出Just another Perl hacker的代码),来分享自己的编程技术。[25]

Perl 社群的官方标志是一个洋葱,不过由于 Programming Perl 一书封面是骆驼的原因,骆驼也常常被用做社群标志。

代码示例

Hello World:

print "Hello, world!";
# Perl 5.12 之后
use v5.12;
say "Hello, world!"; # 多输出一个换行

子程序和控制结构

sub add {
    my ($a, $b) = @_;
    $a + $b;
}
# 5.36
use v5.36;
sub newAddWithSignature($a, $b) {
	$a + $b;
}
my $a = 1, $b = 2;
print "Impossible" unless($a + $b == 3);

标量类型可以变化[19]

my $value;
$value = 123.456;
$value = 77;
$value = "I am Chuck's big toe";
$value = Store::IceCream->new;

发送邮件[26]

 #!/usr/bin/perl
use strict;
use warnings;

# first, create your message
use Email::MIME;
my $message = Email::MIME->create(
  header_str => [
    From    => 'you@example.com',
    To      => 'friend@example.com',
    Subject => 'Happy birthday!',
  ],
  attributes => {
    encoding => 'quoted-printable',
    charset  => 'ISO-8859-1',
  },
  body_str => "Happy birthday to you!\n",
);

# send the message
use Email::Sender::Simple qw(sendmail);
sendmail($message);

Moose[27]:

package Point;
use Moose; # automatically turns on strict and warnings
 
has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');
 
sub clear {
    my $self = shift;
    $self->x(0);
    $self->y(0);
}
 
package Point3D;
use Moose;
 
extends 'Point';
 
has 'z' => (is => 'rw', isa => 'Int');
 
after 'clear' => sub {
    my $self = shift;
    $self->z(0);
};

评价

赞赏 Perl 者认为它功能强大,且适用范围广;但是因为其“有多种方法做一件事”的哲学,使许多Perl程序的代码难以阅读[28],加上它的面向对象功能(5.38以前的)被视为不是真正的面向对象(只是通过模块和 bless 机制做了模拟)[20][29],因此 Perl 遭到批评。

Perl 常常被和其他动态语言比较。最常见的比较对象是Python,著名黑客埃里克·斯蒂芬·雷蒙写了《Why Python?》[30],该文中一个重要的比较对象就是Perl。《A Byte Of Python》[31] 也做了类似的比较。

Ruby的作者(松本行弘,Matz)曾表示,他认为Ruby可以作为Perl的后继者。[32]

参考

  1. The "Artistic License" - dev.perl.org. dev.perl.org. [2018-12-17]. 
  2. Artistic - file on the Perl 5 git repository
  3. Perl Licensing. dev.perl.org. [2011-01-08]. 
  4. 4.0 4.1 About Perl. perl.org. [2020-06-11]. "Perl" is a family of languages, "Raku" (formerly known as "Perl 6") is part of the family, but it is a separate language which has its own development team. Its existence has no significant impact on the continuing development of "Perl". 
  5. 5.0 5.1 Perl Maintainers. perlhist. Perldoc browser. [2023-08-10]. 
  6. The Perl 5 language interpreter. metacpan.org. [2023-07-03]. 
  7. Wall, Larry, Tom Christiansen and Jon Orwant. Programming Perl, Third Edition. O'Reilly Media. July 2000. ISBN 0-596-00027-8. 
  8. comp.sources.unix. Google Groups. Google. 1988-02-01. 
  9. 9.0 9.1 9.2 9.3 The Timeline of Perl and its Culture. 
  10. Kline, Joe. Report from the Perl Conference. 2000-08-21. 
  11. Wall, Larry. State of the Onion 2000. O'Reilly Network. 2000. 
  12. The Perl Foundation. About Perl 6 RFCs. 2000. 
  13. https://docs.raku.org/language/faq. Raku FAQ. 
  14. Perl Contributors. perlfaq1. Perldoc. 
  15. Lee Johnson. CGI.pm. MetaCPAN. [2024-04-02]. 
  16. Perl Contributors. Perl Git Repository. 
  17. Nagpal, D.P. Web Design Technology. India: S. Chand. 2010: 700. ISBN 978-8121927635 (English). 
  18. 18.0 18.1 Perl Maintainers. perlsyn. Perldoc Browser. [2023-07-18]. 
  19. 19.0 19.1 chromatic. Modern Perl. Pragmatic Programmers. 
  20. 20.0 20.1 Perl Maintainers. perlootut. [2023-08-01]. 
  21. Perl Maintainers. perldelta. [2023-08-01]. 
  22. Perl Maintainers. perlclass. [2023-08-01]. 
  23. Grokking the CPAN (PDF). I propose that we cooperate to create a unified structure, much like the CTAN project which has managed to create a collection of canonical sites for TeX 
  24. 24.0 24.1 CPAN front page. [2023-08-06]. 
  25. The Lighter Side of Perl Culture (Part II): JAPH. [2015-11-19]. 
  26. Perl Examples. Perl Learn. [2023-08-10]. 
  27. Karen Etheridge. Moose. MetaCPAN. [2023-08-10]. 
  28. This is Not Your Grandfather's Perl
  29. Really Writing Object Oriented Perl
  30. Why Python?
  31. A Byte Of Python
  32. “我认为Ruby这个名字作为Perl之后的一门语言的名字真是再恰当不过了。”--摘录自O'Reilly访问Matz。