冒号和他的学生们 ——程序员 提高班纪事
21 .后台脚本
操千曲而后晓声,观千剑而后识器 ——《文心雕龙•知音》
摘要:讨论 Perl 、 PHP、 Python和 Ruby语言
“剩下四种动态语言,我们将之归为后台脚本语言 。”冒号说着画了张图表——
用户
前台语言 : Visual Basic , Delphi , JavaScript
平台语言 : Java , C#
后台脚本语言 : Perl , PHP , Python , Ruby
系统语言 : C , C++ , D
机器
引号听得仔细:“我记得您开始是把这些语言划分为 C族静态语言、非 C族静态语言和动态语言三类的。”
冒号解释:“那是按语法来划分的,偏重理论;现在是按应用来划分,偏重实践。”
句号旋即联想到:“这种分法貌似三层架构——前台语言对应表现层;平台语言和后台脚本语言对应业务逻辑层;系统语言对应数据层。”
“的确有些神似,但千万不可混淆。”冒号提醒道,“三层架构( three-tier architecture)是模块设计上的逻辑划分 ;而这里是按语言应用范围进行的物理划分 ——与用户交互的是前台语言 ,与机器交互的是系统语言 ,介于其中的为前台提供服务同时又需要底层系统服务的是后台语言 。”
逗号询问:“后台语言又细分成平台语言与后台脚本语言?”
“这是基于程序( program)与脚本( script)、静态与动态而分的。”冒号进行说明,“其实 Perl, PHP, Python和 Ruby都有自己的虚拟机( Virtual Machine),从这种意义上说它们也可作为平台语言。但在实际应用中,它们没有 Java平台和 .NET平台那种凝聚力和核心作用,通常作为轻量级的解决方案。”
问号想探个究竟:“这是由于它们都是动态语言的缘故吗?”
冒号回答:“理论上动态语言同样能承担大型应用,但实践上它们多作为粘合语言或用于中小型应用。用句时髦的话来形容,暂时还是主流的配角 或非主流的主角。 毕竟在效率、类型安全、可用资源、开发工具 、技术支持等方面,它们与 Java、 C#相比尚有一定差距。另外它们同属‘草根’语言,虽有开源 社区的大力支持,在影响力上与后者未可同日而语。”
叹号揣测:“说不定在不久的将来,动态语言也会成为主流的主角。”
“世易时移,殊难逆料。但有一点可以肯定,语言的发展趋势一定是动静结合、刚柔并济。”冒号断言,“一方面以 Java和 C#为代表的静态语言中嫁接了动态语言的枝条;另一方面以 Java和 .NET为代表的平台与动态语言的交壤地带也在逐步扩大。比如 JRuby允许 Ruby与 Java之间互相调用,类似的还有 Jython、 IronRuby、 IronPython等等。此外值得一提的是,动态语言最活跃的舞台当数 LAMP, L-A-M-P。”
引号接茬:“ L是 Linux, A是 Apache, M是 MySQL, P是 PHP。”
冒号补充道:“ P也可指 Perl、 Python,甚至 Ruby。”
句号调侃:“可惜 Ruby的‘ R’比‘ P’多了一根尾巴。”
“有人为了自圆其说,干脆让 P表示‘ Programming language’,这下所有语言都囊括其中了。老外就喜欢玩这种首字母缩略( acronym)的文字游戏。”冒号语带调笑,“前面我们曾提及,网络应用是生长动态语言最肥沃的土壤,而 LAMP就是这块土壤上搭建的平台。作为开源网络平台, LAMP以其开放灵活、开发迅速、成本低廉等特色而与 Java平台和 .NET平台鼎足三分,尤其受中小企业的欢迎。 LAMP中 Linux是操作系统, Apache是 Web 服务器, MySQL是数据库 系统,而我们当下最关心的是‘ P族语言’: PHP、 Perl、 Python还有 Ruby。”
问号建议:“作为动态语言,它们的共性上节课已经谈了不少,能说说它们的个性吗?”
“它们的个性极为鲜明: Perl 凝练晦涩, Python优雅明晰, Ruby精巧灵动, PHP简明单纯 。先看老大哥 Perl,它博采众家之长,综合了 C语言的结构、 sed的正则表达式、 AWK的关联数组 (associative
array)、 Lisp的表( list)和 Unix
Shell的命令,此外还有借鉴了一种语言,你们知道是哪种吗?”冒号忽然卖了个关子。
逗号猜想:“应该是某种 OOP语言吧。”
“ Perl中确有不少 C++的影子,但它的对象模型在 5.0以后才引入,典型的半路出家,远不如前面的特征那么自然。与其说是一种自然而然的发展,不如说是在 OOP潮流裹挟下的一种身不由己的迎合。真正深入骨髓的借鉴是自然语言。”冒号给出了答案,“ Perl的发明者 Wall是一名语言学家,他认为程序语言应该与自然语言一样,简洁自然、易读易写、表达多样、不拘一格。 Perl还有不少的格言或哲学,使得编程语言一改严谨刻板的面孔,散发出浓郁的人文气息。”
叹号幽了一默:“我见过 Perl的代码,人文气息没闻出来,但我怀疑有乙醚气息——看一会就觉得晕晕乎乎的。”
众人大笑。
“有人仅用一行 Perl代码就实现了 RSA算法,你看了那还不得当场晕倒啊?”冒号打趣道,“ Perl的各种魔符好似一把把锋利的剪刀,做起文本裁剪之类的工作来游刃有余。这是它最大的长处,当初 Perl就是 Wall用来做 Unix系统管理 的,以后在 CGI上的广泛应用也得益于此。但它既精练又复杂,影响了可读性、一致性、整洁性和可维护性。不熟悉该语言的固然如读天书,熟悉语言而不熟悉问题的也颇费思量。相比之下 Python被认为是 Perl有力的挑战者,不仅在于它天然的 OO设计,更重要的是它对程序员友好度大大超过 Perl。 Python也有一系列的被称为禅( Zen)的哲学,不少与 Perl是针锋相对的。比如: Perl认为做一件事可以有多种方法,而 Python认为一件事应该最好只有一种方法; Perl追求语言的表现力, Python追求简单优雅; Perl喜欢隐性暗示, Python强调显性明示; Perl强调紧凑, Python强调松散; Perl的语法和语义丰富, Python的语法和语义简单而类库丰富。或许 Python最让人不习惯的是它对空白符敏感性。”
引号感到惊奇:“对空白符敏感?这个倒真怪异。”
冒号见惯不怪:“虽然有点违反习惯,但非常符合 Python一贯的规范简洁的风格——一方面从语法上保证了良好的编码风格;另一方面,每个代码块不再需要起始的大括号或 begin/end之类的,减少了的代码行数。此外许多人抱怨 Python中的自引用 self太多,殊不知这也是它倡导显式表达的一种体现。”
叹号好奇地问:“ Ruby怎么样?据说它将取代 Java。”
“不要轻言‘取代’二字。”冒号规诫道,“ Java没有取代 C++,也不会被 Ruby取代,至多只是一种再分配。不过 Ruby的确是门很可爱的语言,兼具 Perl的表现力和 Python的可读性。 Ruby背后最具特色的理念是:关注程序员使用语言时的感受超过语言本身的功能。通俗地说,兵器的称手比锋利更重要;文雅地说,应给予程序员更多的人文关怀。就拿代码块( block)和迭代器( iterator)来说,虽然均非 Ruby首创,但其语法最为赏心悦目。类似的例子比比皆是。然而真正让 Ruby变得炙手可热的是 web应用框架 Ruby on Rails( RoR)的成功,它们还催生了 Java平台上的 Groovy语言和 Groovy on Grails框架。 RoR奉行的 CoC( Convention over Configuration)和 DRY( Don't
repeat yourself)原则以及 MVC架构看似了无新意,但与 Ruby结合之后,便如一只猱身而上灵猫,立刻衬托出 Java和 .NET大象般的身影。”
逗号有些怀疑:“框架竟然捧红了语言,框架真有这么重要吗?”
“如果 Web应用中动态页面较少或业务逻辑不复杂,框架的价值并不大。以前 CGI编程就是往 Perl之类的代码中嵌入 HTML代码,如同 Java中的 Servlet; PHP则单纯地在 HTML代码中插入 PHP代码,如同早期的 JSP。没有 MVC,也不管什么三层架构,更没有 ORM。但是——”冒号拖了个转折音,“一旦业务逻辑变得复杂,开发人员增多,手工作坊式编程开始捉襟见肘,引入框架这个流水生产线来提高生产力便是大势所趋。”
句号不解:“我想 Perl、 Python和 PHP一定也有不少框架, Java中的框架更是泛滥成灾,何以独独 RoR脱颖而出?”
冒号作出分析:“各种 web应用框架是不少,但在 RoR之前轻量级套餐式解决方案 并不多。 Perl中的 Catalyst、 Python中的 Pylon还有 PHP中的 CakePHP等都是效仿之作。此外, Perl和 PHP由于过于流行,反而有不少的历史包袱,人们习惯了将表示逻辑和业务逻辑编织在一起。至于 Java企业解决方案,框架太多,搭配组合更多,增加了选择的难度。即使采用最常见的 Struts+Spring+Hibernate组合,维护起来也比 RoR繁杂得多。”
叹号愈发担忧:“听这意思, Java还是危险啊!”
“言之过早。”冒号不以为然,“首先 RoR还有待进一步检验,目前无论是应用广度还是深度上尚无法与 Java相提并论;其次 Java在性能、安全等方面还是有不少优势,而这些对于大型和关键性的应用来说尤为重要。即使在中小型 web应用中, RoR较之 PHP还远为不及。”
问号接下话题:“ PHP为何如此流行?”
“因为它简单、专一。”冒号答得很干脆,“与 Python和 Ruby一开始就定位通用语言不同, PHP是专为网络而生的。同早期的 Perl相似, PHP起初主要起文本过滤器的作用,只不过 Perl多处理文件流( file stream),而 PHP多处理套接字流( socket stream)。 PHP的语法简单,且为网络应用度身定造,受到网络开发人员的追捧当在情理之中。但它实用而不完美,比如:变量名大小写敏感而函数名大小写不敏感;函数命名规则不一致;不支持 namespace和 unicode;与 Perl一样,它的对象模型不是先天的,直到 PHP
5才真正完善;对线程支持不足;相比 Perl、 Python和 Ruby,它的功能稍显单薄等等。”
引号突然想起:“我记得您在第一堂课提到 PHP还能用于桌面应用。”
“不仅 PHP, Perl、 Python还有 Ruby,都能作为前台语言来开发命令行或图形界面的应用。同样地, VB、 Delphi和 JavaScript也能作为后台语言。现代语言都趋向通用化和全能化,以争取更多的生存空间。”言及于此,冒号收住话题,“语言简评该告一段落了,现在请大家每人写一句对本节课的感言。”
众人沉思片刻,挥笔而就——
叹号——没有最好的语言,只有最合适的语言。
逗号——没有糟糕的语言,只有糟糕的程序员。
问号——没有一种语言是万能的,只会一种语言是万万不能的。
引号——废除对语言的宗教信仰,建立对语言的哲学思维。
句号——编程就是在人脑和电脑之间寻找最佳平衡点的过程。
冒号读罢大悦,顺手一掌拍出五记马屁:“精彩之极!可谓字字珠玑、句句联璧啊。兹决定,给诸位的奖赏是——下课!”
众人欣然领赏而去。