频道栏目
IT货架 > > 正文
Cultured Perl: 吸引 C 和 Java 程序员目光的Perl 5.6
网友分享于:Aug 2, 2018 1:57:21 PM    来源: IT货架   
Cultured Perl: 吸引 C 和 Java 程序员目光的Perl 5.6Perl
有时甚至令有阅历的轨范员也感想沾染头疼,因为他们发明一不留意就会写出不置能否的语句。但这类在组织、特色零星方面的恍惚性从其他一方面显示了
Perl 措辞丁壮夜的能力。究竟 Perl
措辞最最先的设计初衷就是进展能用多种体式格式来抵达不合目的。这里我们将要商酌 Perl 5.6 中那些最随意疏忽搅浑的特色,并将它们与
C/C++/Java 中呼应的特色做比拟。次要围绕 “Natural Language
Principles in Perl” 中的绳尺睁开(Larry Wall 著,参看本文末尾的
资料 部份),因为它们是 Perl 最能与 C、C++ 和
Java 措辞判袂开的地方。其余,关于 Perl 语法的组织可以在 “perldoc
perlsyn” 参考文档中找到,其他一本值得举荐的 Perl 指南读物则是
Programming Perl。(参看
资料
部份)Perl
正文器初学者立时就会发明 Perl 中恍如没有任何编译器。现实上,Perl
剧今除夜多是由 Perl 正文器直接运转的,例如 UNIX 零星下的
“Perl”、DOS/Windows 下的 “perl.exe” 就是 Perl 正文器。而在 MacOS
中则不需求这些正文器。您可以试试看若何运转 Perl
剧本。首先在您的操作零星上启动呼应的 Perl 正文器,或是在 MacOS
零星中直接运转。在除夜多半零星中,文件尾符号(UNIX 零星中为
Control-D)用来泄漏表现用户输出停止。是以在 UNIX
零星中,上面这个剧本将能获得 “5+6″ 的竞赛争辩效果:从最庞杂的 Perl 轨范着手> perl (Perl is waiting for user input here, because no script name is given) print 5+6 You press Control-D here 可以看到 Perl
正文器运转了这个只需一行的剧本轨范,并输出该表达式的竞赛争辩效果
11。Perl 正文器有许多选项。例如,-e 选项泄漏表现将敕令行的输出作为剧本文件来实行,是以上面的剧本例子也可以这样完成:在敕令行输出
perl -e'print 5+6' (留意,要用单引号将敕令括起来)。而 -i 选项则相反于经由进程一个过滤器,准许在文件等不合的位置中止编纂。-n 和 -p 选项能让轨范员掀开或关闭输出。-w 选项与 C/C++ 中的 “-Wall” 编译选项相反,都可以对轨范中荫蔽成就给出警告信息,但与 -Wall 不合的是,-w 功用在轨范运转时也是被激活的。速度和
Benchmark人们经常拿 Perl 与 C/C++ 比拟,并埋怨 Perl
运转速度缺少快。某些时辰这真实其实是现实,然则并非永远如斯。我建议您在以为
C 或 C++ 更快之前,行使 Benchmark 模块试试看 (perldoc
Benchmark)。其余,Perl 能很随意地与 C/C++ 代码或库衔接,且某些 Perl
内置函数其实不比 C 代码慢,如排序或打印等。这里再次提醒您在深信 C/C++
比拟快之前,先行使一下 Benchmark 模块。要记住,过早的优化经常是缺陷的本源。假定您在 Perl
中写了一个原型,并用其他措辞来重写是没有成就的。原型意味着可以随意地垦荒。与 Java 比照而言,Perl 也可以很好地责任。Perl 不象 Java
那样擅擅长线程,但它的 Tk GUI 界面临象箱却比 Java 的 Swing GUI
库要好。而且 Java 代码老是可以衔接到 Perl
轨范中,反之亦然。是以,有时您可以经由进程某种水平上的连络,使得轨范在两方面都做得很好。异常、编译和文档Perl 经由进程 CPAN 中的模块或是其内置函数 eval() 来抛出异常。就似乎在
C++ 或 Java 中经由进程 try/catch 代码块来处置责罚异常一样,eval
函数能处置责罚某个代码段或某个字符串操作的异常。现实上,Perl 轨范在运转之前照样需求编译的,只是和 C/C++/Java
的编译体式格式不沟通。在设计和效果上,它和 Java
的字节正文进程很相反。关于编译的更详实内容,可以参阅 “perldoc
perlrun” 和 “perldoc perlcc” 文档。可用 POD 花招来将文档嵌入 Perl 轨范。这类文档嵌入体式格式比 Javadoc
花招(仅适合于 API 文档)要通用,但比不上 C/C++/Java 的正文。即便和 C、C++ 或 Java 比拟起来,Perl
轨范也不算是一种组织性强的措辞。例如,BEGIN
语句块会被首先实行,但它可以在轨范中多次声名。界说、变量和函数体可以在轨范的随意率性位置泛起,Perl
所供应地丁壮夜功用可以最好地知足这类随意性。因为这类散漫组织、嵌入的正文、和为追求随意而致使的使人搅浑的语句,使得书写
Perl 轨范更像是在写一封英文函件。Perl
的容错能力Perl 比 C/C++/Java
更能容忍一些恍惚地写法。例如可以用逗号来分隔语句或函数的参数:语句之间或函数参数之间的分隔符print 'Hello', ' ', 'there.', "/n"; # print "Hello there/n" foreach (1..10) { my $i; $i = $_ * 2, print "$i/n"; # print evens from 2 to 20 }Perl
能尽最除夜可以地消弭这些语句可以激起的歧义。虽然,有些时辰仍有没法处置的歧义(在这一点上,Perl
就象英语一样)。Perl
中其他一个随意疏忽激起歧义的地方在于:变量经常会被隐含行使。例如,”print”
语句缺省时会打印 $_ 变量的值。在其他一些隐约的语句操作中,$_
变量也是它们的缺省值,这就组成了一种杂沓。例如:隐含行使变量$_ = "hello"; s/hello/hi/; # $_ is "hi" now print; # prints "hi"这里你可以看到,行使缺省变量能让编程随意精练。也就是说,Perl
和英语相反,经由进程某种恍惚性来简化表达式。一项责任多种完成
(There’s more than one way to do it ,TMTOWTDI)一切的措辞在处置成就时都有本人的方法。在 C 里面,for()
轮回是在一定局限内重复的最好方法;在 Java
里,静态函数的挪用是直接经由进程类而不是某个实例。但对不合件责任,Perl 至多有两种处置方法。TMTOWTDI 绳尺就是
Perl 的座右铭,各类处置责罚上的差异在 Perl 编程中是深受勉励的。上面来看一个打印数组元素的例子。一切的表达方法都抵达不合目的。打印数组元素print foreach @array; foreach (@array) {print}; map {print} @array; print @array;要理解以上这些代码的独一路径就是掌控一切 Perl
的语法。不要忧郁哪类方法才是准确的,因为完成不合目的老是有多种准确的方法。斟酌这些不合的表达体式格式,您可以更深化体味
Perl 的这个座右铭。其他,虽然一个责任的完成有多种方法,但这其实不虞味着一切方法都是准确的。常日情形下,更有可以写出的是一些缺陷代码。为了担保代码的准确性,最好尽量行使那些
Perl
内置的函数,而较少行使本人所编写的函数,而且留意证实并记载这些不那末显著的方法。正则表达式假定没有初始化,正则表达式很有可以组成一片杂沓。除夜多半人都信任正则表达式是由
Kalahari bushmen
发明的,它渗透到了除夜学的竞赛争辩机科学编程的一切方面。Perl 的正则表达式是从 shell 剧本轨范和 awk/grep
对象中连续而来的。但它的能力却远远跨越了副本的模子。根蒂根抵的正则表达式长短常随意疏忽书写的,但难以读懂。例如 “con/w+” 和
“contra”、”contrary” 婚配,但与 “pro” 或 “con” 都不婚配。然则在
Perl 5.6.0 中,正则表达式被固化了。Unicode
字符集、方法内随意率性代码操作、flag
toggles、前提表达式和其他特色都被添加到正则表达式库中。对初学者的一个最好的建议就是:首先辈修最根抵的正则表达式(参阅
资料 部份,或 “perldoc perlre”
参考手册),稍后才进一步进修那些庞杂的初级特色。因为正则表达式必需全写在一路,两头没有装备添加正文,这就让它们成为一切
Perl 代码中最难读懂的一部份。是以建议人人信写已成型的代码。在 C/C++/Java 中正则表达式属于内部的函数包,但 Perl
是今朝最佳的正则表达式查找和代换对象。在少多半情形下,它可以会比纯
C 轨范慢一些,但对那些纯洁面向正则表达式的成就,Perl
仍然是您首选的对象。标量、数组和哈希散列和 C、C++、Java 中变量不合的是,Perl
的变量的类型是由其名字决意的,而且会自动初始化成呼应类型。这一点让
Perl 初学者感想沾染很不习惯,但它异常地直不雅观不雅观而易于理解。笔者举荐行使 “use strict”。经由进程它可以担保变量外行使之前声明,从而避免打字缺陷等激起的轨范缺陷。假定没有做到这一点,则有可以碰着上面这样的成就:一个罕有的打字缺陷$i = 5; print $j; # print $i此例子中,轨范员副本要打印变量 i 的值,效果却敲成了 j。Perl
其实不会感想沾染这段代码有什么成就,它会连续实行打印语句,显示 $j
的值即什么都没有。有些时辰,Perl
的自动生成对象真实其实很有用,但以我的阅历来说,最好照样用 “use strict”
来关丢失落这一自动功用,从而避免上述成就。Perl 变量可所以标量 (scalars)、数组 (arrays)或哈希散列
(hashes,又叫做联络关系数组)。(现实上,Perl
中有多种数据类型,然则轨范员其实不会直接面临它们。)其余也可所以引用,常日它们也是一种标量类型。个中标量称号以
“$” 开首,数组名以 “@” 开首,而散列则以 “%” 开首。标量是 Perl
中最庞杂的数据类型。每一个标量都有独一的值,或是字符串或是引用。在需求的时辰,字符串和数字可以互相转化。这常让初学者感想沾染欣喜异常。看一下这个例子:标量$i = "hi there"; print 1+$i; # prints 1个中标量 $i 的值是字符串 “hi there”,它对应的数值为 0。是以 1 +
“hi there” 的值为 1,轨范运转效果为 1。不外这其实不虞味着 Perl
正文器在对某个标量分离斟酌其字符串类型和数字类型。现实上,在内存中只是一个含有某个值的标量。假定在数值运算的语句中(如加法),这个标量值就转化成数值方法;假定在字符串操作语句中(例如打印),则以字符串方法实行。但不管以什么方法运算,该标量变量实质上只需一个值。不决义的标量的值为 “undef”。假定在 C/C++/Java
轨范中,您可以将其他值与 null 比拟,但在 Perl
中却不能拿任何器械来与 “undef” 做比拟。可用这样行使 defined()
函数:Use of the ‘defined()’ function$i = "hi there"; print $i if defined $i; # prints "hi there" undef $i; # set $i to be undef print $i if defined $i; # prints nothing数组实质上就是一组标量。假定需求,数组巨细可以自动修改,有点象
Java 中的 Vector 类。C 和 C++ 中没有与 Perl
数组类型相当的器械,但它们也有一些供应相反功用的库(如
STL)。数组的一个幽默特色在于,数组的标量数值等于它的元素个数:数组中的元素个数@a = ("hi there", "nowhere"); print scalar @a; # prints 2 push @a, "hello"; # add "hello" at the end print scalar @a; # prints 3散列与数组相反,但里面的标量并非依照位置排序的,而是经由进程其他一个标量(必需是独一值)来中止索引。例如一个用
social security number
作索引的名字列表就是一个散列。将某个键值拔出到散列后,该散列会自动扩展年夜。散列与
Java 中的 HashMap 和 Hashtable 类很相反。引用类型其实也是标量,它们相反于 C
措辞中的指针,可以指向任何器械。这就准许 Perl
生成一个散列的数组、数组的散列、散列的散列、或是数组的数组(多维数组)。有多种方法来获得引用所指向的内容,或直接行使引用的名字、或行使
“->” 操作符。引用是一个触及局限异常广的成就,可以参考 “perldoc
perlref” 参考文档来获得更多相关信息。C 和 C++ 只需一些固定类型的标量。当轨范员要行使数组或哈希散列时,不能不去行使钩子 (hoop) 或是 STL 等内部库。Java 中有相当于 Perl 里数组或散列功用的类库,但它们在 Java
措辞中并非那末直接。好比说要对散列上一切元素做操作所需求的时辰除夜约是
Perl 的三倍。对散列中一切元素中止操作的 Java 代码import java.util.Enumeration; import java.util.Hashtable; Hashtable hi = new Hashtable(); // fill in hi's values // we can use an Iterator, still a lot of typing for (Enumeration enum = hi.elements(); enum.hasMoreElements();) { Object o = enum.nextElement(); // do something with o }对散列中一切元素中止操作的 Perl 代码# note that this even includes the definition and initialization of # the hash, and still is more compact than the Java code! %hash = { a => "hi", b => "hello" }; foreach (values %hash) { # do something with $_ }Perl
的缺憾Perl 穷困 C、C++ 和 Java
中的许多特色,但它究竟是一门完整不合的措辞。这几种措辞中甚至有许多特色是互相抵牾的。例如
Java 只支持单一连续,而 C++
则可以有多个父类。这类有冲突的情形下虽然弗成能连续一切措辞的特色,Perl
有它本人处置责罚成就的方法。因为 Perl 轨范可以被衔接到 C 的库中(现实上,这也就是 Perl
运用普遍的启事之一),这就使得几近没有任何 C 或 C++ 能做而 Perl
不能的责任。与 C 和 C++ 比照而言,Perl
有时完善的是运转速度。这真实其实是一个成就,然则经由进程优越的编程算法和
Perl 内置函数的行使,就可以够打败这一瑕玷。Perl 还不能直接行使 C 和 C++
的库。必需经由进程不合的模块和绑定,才华够将这些库中的常量和函数功用转化成顺应
Perl 的样子。这就会致使垦荒和轨范运转的速度下降。但因为 CPAN
库中宣布了除夜量这些方面的模块,是以这个成就并非那末难以处置,在演习编程技巧手段方面,Perl 其实不象 C 和 C++
那样深切人心。它是一门年迈的措辞,虽然很受迎接,但并未被人们普及收受接管。然则,除夜多半的
UNIX 零星上都安装了 Perl,且其他的操作零星也都支持 Perl。Perl
支持单一连续或多连续、封装和多态,但这仅仅是经由进程内部模块或轨范员的协同来完成的。也就是说,Perl
措辞本人并没有严厉的面向对象编程划定礼貌,需求轨范员本人来完成面向对象。这一点有好也有坏,这就要取决于轨范员或项目本人了。Perl 的线程和不合字符编码(Unicode)支持远远落伍于
Java,也略微次于 C/C++。Java 从最最先设计就支持线程和 Unicode,而
C/C++ 则比 Perl 具有更多的时辰来调解这方面的准确支持。在 Perl
中,对线程和 Unicode 的支持仍处于起步阶段,但 5.6.0
之后的波动版本宣布之后这一点将获得改不雅观不雅观。Perl
的优势对 C/C++/Java 轨范员而言,Perl
在某些方面的优势是无价的。例如正则表达式在 Perl
中的完成是易如反掌的,但在 C、C++ 或 Java
中完成起来却很费事。隐含的函数声明、不严厉的语法、和象日用文档似的轨范组织使得
Perl 更具吸引力。Perl
其实不适合于一切人。它需求读者去顺应,却收受接管它的所出瑕玷和优点。我们并非感想沾染
Perl
酷才收受接管它,而是因为它真实其实是一种异常好的对象。假定在处置某个成就时行使其他措辞更适合,那末就理应摒弃
Perl。一个好轨范员的手头老是有好几种有用的对象。Perl
有一些小的缺少,但那些不知疲困的轨范员会疏忽丢失落这些瑕玷。假定真实其实需求线程和
Unicode
支持,或是严厉的面向对象编程,那末你只好凭证这些需求来选择其他更适合的措辞了。Perl
是一门通用的无邪的措辞,可以象胶水一样将其他许多不合的模子粘合起来。它可以完成任何进程或函数的算法。常日情形下,Perl
会除夜除夜增加垦荒的时辰,因为它对某些罕有的责任(例如对散列表中的一切元素做操作)只需求少许的代码。最主要的是,Perl
编程老是相当于一个幽默的进修进程。
相关板块推荐 Java PHP Python

广告服务联系QQ:1134687142 | 网站地图

版权所有: IT货架- 内容来自互联网,仅供用于技术学习,请遵循相关法律法规. 京ICP备11030978号-1