作者 Hal Fulton 刚刚更新了他的经典之作—— The Ruby Way (《Ruby 之道》,已由人民邮电出版社出版)_。 Hal 之所以要这么做的原因是由于十月第三周要赶上 RubyConf 2006 ,_ 并且要配合着 Addison Wesley 专业 Ruby 系列图书的启动。在这次 InfoQ 的独家采访中,Hal 回答了贯穿整本书的问题:
什么是 Ruby 之道?
Let us prepare to grapple with the ineffable itself, and see if we may not eff it after all. 让我们时刻准备着向那些所不能说的挑战,看看最终是不是可以说。
——摘自 Douglas Adams 的作品 Dirk Gently’s Holistic Detective Agency
我们所说的”Ruby Way“是什么意思? 我认为有两个相关方面: 一个是 ruby 的设计哲学 ; 另一个是它的使用哲学. 设计和是使用相关这是自然的事情, 无论硬件还是软件 ; 否则生物工程学如何产生? 如果我制造了一个设备并且在上面装了一个把手, 那是因为我希望别人可以通过把手使用这个设备.
Ruby 有一种难以名状的品质让其与众不同。我们可以从这门语言的语法和语义上,也可以从用 Ruby 编写的代码中窥豹一斑。但一旦我们辨别了其中品质,我们就知道怎么回事了。很明显 Ruby 不只是创造软件的工具,而且是一种有主见的软件。为什么 Ruby 程序的使用原则不同于 Ruby 语言本身的使用原则?毕竟 Ruby 是高度动态和可扩展的。这两种层次的 Ruby 用法有所不同,原因可能是现实世界的不协调性。但总而言之,思想过程应该是一样的。Ruby 语言可以通过 Ruby 来实现,用 Hofstadter 风格,虽然本文撰写时尚无例证。
我们不常想到”Way“这个词的本义;但是它被赋予两个重要涵义。一方面,它意为方法或者技术,但它也意为道路或途径。显然这两种意思是相关的,而且当我说“Ruby 之道”的时候,两种意思都有。
所以我们我们所讨论的不仅是一种思考过程,而且是我们追随的一种做事方式。即使最伟大的软件领袖也不能宣称达成完美,而只是追随着完美主义。而且世间做事的方式不止一种,但我只能讨论一种。传统智者说:形态取决于机能。而且传统智者当然通常是正确的。但是 Frank Lloyd Wright (在自己的领域)曾经说过:“形态取决于机能——已经被曲解了。形态和机能本为同一物,源于自性本体。”
Wright 所说何意?我想他想表达的意思是真理不是你从书本上学到的东西,而是从经验中修证而来。
但是我以为 Wright 表达的真理在某些方面易于理解。他是一个伟大的简单性倡导者,他曾说过:“一个建筑师最有用的工具是草图板上的橡皮擦。”
所以 Ruby 美德之一是简单性。我可以在此主题上引用其他思想家的话么?按照 Antoine de St. Exupery 的说法,“完美之道不在于无可添加,而在于无可剔除。”
但是 Ruby 是一门复杂的语言。我怎能说它简单呢?
如果我们更好地理解了宇宙,我们可能找到一种“复杂性的永恒法则”——一个现实中扰乱我们生活的事实,例如熵,以至于我们不能逃避,只能改变其分布。
而且这就是关键。我们不能逃避复杂性,但是我们能把它推到一边。我们能将其埋葬于视野之外。这就是工作中古老的黑盒原则;一个黑盒执行一个复杂任务,但是从外面看它具有简单性。
如果你还有耐心来听我引述,爱因斯坦的一句话此处非常适合:“任何事物都应简单到极致,而非更简单。”
所以从 Ruby 中我们看到了从程序员视角诠释的简单性(如果不是从 Ruby 解释器维护者的角度来看)。但是我们也看到了妥协所导致的特性。现实世界中,我们必须妥协一点。例如 Ruby 程序中的每一个实体必须是一个真的对象,但是某些值比如整数型是直接存储的。为了让计算机系学生感觉更亲切,我们已经牺牲了一些优雅的设计来达成实现的可行性。实际上,我们牺牲了一种简单性来换取另一种简单性。
Larry Wall 关于 Perl 所说的话仍适用于此:“当你用小型的语言说话时,话会很冗长。当你用大型语言说话时,话会很简短。” 英语同样如此。生物学家 Ernst Haeckel 可以用三个词说出“Ontogeny recapitulates phylogeny”是因为他可以支配这些针对特定语义的强大词汇。我们允许语言的内在复杂性,因为这使得我们把复杂性从每个个体的表达中移走。
我想这样表达这条原则:不要写 200 行代码,如果 10 行可以搞定。 我理所当然地认为简洁是一个好东西。短程序段将占据程序员更少的大脑空间;作为独立实体,它将更易于理解。作为一个令人愉快的副作用,这种代码编写的时候,能钻进来的 bug 更少。
当然我们必须牢记爱因斯坦关于简单性的告诫。如果我们赋予简洁太高的优先级,我们终将无可奈何地陷入令人困惑的代码之中。信息理论告诉我们,压缩数据统计上接近于随机噪音;如果你看过 C,APL 或者正则表达式的标记法--尤其是写得很糟糕的--你已经直接地经历了这个事实。“简单,但不要太简单”;这就是关键。拥抱简洁,但不要牺牲可读性。 众所周知,简洁和可读性都好。但有一个深层次原因,它太根本了以至于我们时常把它忽略。这个原因是计算机为人而存在,反之不然。
过去的日子里,情况几乎相反。计算机耗费了数百万美元并且吃掉了上千瓦的电。人类表现得好像计算机是一个神,而程序员是卑贱的附属品。计算机一个小时的开销要比人一个小时大得多。当计算机变得更小和更便宜,高级语言也变得越来越流行。它们从计算机的角度看是低效的,但是从人的角度来看是高效的。Ruby 简直是一个你怎么想就怎么写代码的语言。有些人实际上称之为VHLL(Very High-Level Language);虽然这个术语没有好好定义,我想它用在这里正合适。
计算机应该是仆人,而不是主人,而且如 Matz 所说,聪明的仆人应该通过几条简短的命令就能完成复杂的任务。整个计算机科学的历史中,这已经成为了真理。我们从机器语言开始,然后进化到汇编语言,之后步入高级语言。
我们这里讨论的是一个从以机器为中心的语法转移到以人为中心。依我看来,Ruby 是一种人本主义编程的优秀典型。
我想岔一下话题。有一本 80 年代出版的小书叫做《编程之道》。书中字字珠玑,但是我只想复述这句:“程序应该符合’最小惊异原则’。这是什么原则?简单地说就是程序应该以让用户惊异最小的方式响应用户。“(当让对于语言解释器来说,用户就是程序员。)
我不知道是不是 James 铸就了这条格言,但是他的书使我第一次了解到这段话。这是一条在 Ruby 社区广为人知并且频繁引用的原则,虽然通常被称为最小诧异原则或者 POLS(本人更喜欢 LOLA)。
无论你怎么称呼它,这条规则很有效,并且成为了整个 Ruby 语言的开发的指导原则。这也是开发 Ruby 库或者用户接口的指导原则。
唯一的问题当然是不同的人所诧异的事不一样。对象或者方法“应该”如何行为没有统一的共识。我们可以尽力争取一致性,争取证明我们的设计决策,而且每个人能够训练自己的直觉。
对于此问题,Matz 说过“最小诧异”应该指的是他自己是设计者。你的想法和他越接近,Ruby 让你诧异越小。并且我向你保证,效仿 Matz 对于我们大多数人来说不是坏主意。
无论一个系统从逻辑上如何构建,你的直觉都需要学习。每一门编程语言都是自己的世界,基于自己的一系列假设,自然语言亦是如此。当我学德语时,我得知所有名词都要大写,除了 deutsch。我对教授抱怨,毕竟这是语言的名字,不是么?他笑着说,别跟它打架。
他教我的是让德语是德语。延伸来讲,这是对于从其他语言转到 Ruby 的金玉良言。让 Ruby 是 Ruby。别让它成为 Perl,因为它不是;不要让他成为 LISP 或者 Smalltalk,同样不是。另一方面,Ruby 具有这三门语言的的共性。跟随我们的期望来开始,但是与其相左时,别跟它打架。(如果 Matz 不同意这个改变是必要的)
今天每个程序员都知道正交原则(更好的术语是“正交完备性”原则)。假设我们有一对坐标轴,一根轴定义了一系列可以比较的语言实体,另一跟轴有一些属性或者特性。当我们说正交,我们通常指这两个轴所定义的空间和我们逻辑上定义的一样完整。
部分 The Ruby Way 是争取正交性。Array 某些方面和 Hash 类似;所以对他们的操作也应该类似。当进入他们行为不同的领域时,操作才不一样。
Matz 说“自然性”通过正交性来评估。但是如何理解什么是自然性或者什么不是可能需要一些思考和编码。Ruby 争取对程序员友好。例如,许多方法有别名,并且都返回数组的实体个数。变体指向同一个方法。有些人认为这是一个令人困惑的或者坏的特性,但是我认为这是一个好设计。
Ruby 争取一致性和规律性。这点没有任何神秘的;生活中的每一方面,我们都渴望事物是有规律和对等的。机敏的是学会何时违反这些原则。
例如,Ruby 习惯在预测行为的方法名后面加个问号“?”。这点不错,它让代码清楚,让命名空间更易于管理。但是更有争议的是类似的惊叹号“!”的用法,标明方法具有破坏性和危险性,从它们修改了接受者这个意义上。争论起源于并非所有破坏性的方法都通过这种方式标注。我们不应该保持一致性么?
不,实际上我们不该。一些方法很自然地改变接受者,例如 replace 方法和允许给类属性赋值的”writer”方法;我们不应该为每一个等号赋值的后面都加一个惊叹号。一些方法有争议地改变接受者的状态,这种情况太频繁,以至于不能用这种方式标记。如果每个破坏性的方法都以“!”结尾,我们的程序很快就会像多级市场公司的销售手册一样。
你注意到相反力之间的张力了么,一种违反所有规律的趋势。让我用 Fulton 第二定律来陈述它:所有规则都有例外,除了 Fulton 第二定律。我们在 Ruby 里看到的不是一种“愚蠢的一致性”,也不是一系列简单规则的刻意坚持。实际上,The Ruby Way 的部分是它不是一个僵化,不灵活的方式。在语言设计中,Matz 曾经说过,你应该“跟随你的心(follow your heart)”。但 Ruby 哲学的另一方面是:不要害怕运行时的变化;不要害怕动态性。这个世界是动态的;为什么编程语言应该是静态的?Ruby 是现存最动态的语言之一。
我想据理力争的另一方面是:不要成为性能问题的奴隶。当性能不可接受时,这个问题一定会被处理,但通常它不应该是你考虑的首要问题。宁要优雅不要效率,在效率不是关键的地方。如果你正在写一个可能以不可预料的方式运行的库,性能可能从一开始就是关键。
当我观察 Ruby,对于一个复杂的物理学上 n-body 回忆者问题,我觉察到了不同设计目标的一种平衡。我可以想象它可以建模为 Alexander Calder Mobile。这可能是交互自身,其具体表现 Ruby 哲学而不是独立的部分。程序员知道他们的手艺不只是科学和技术,而是艺术。我不愿说计算机科学中有宗教思想,但就你我之间,确实存在。(如果你还没有读 Robert Prisig 的《禅与摩托车修理技术》Zen and the Art of Motorcycle Maintenance,我建议你读一读)
Ruby 从人类力求创造实用并且美好的事物中诞生。用 Ruby 写的程序应该源于同一天赐本源。此本源,对我来说,便是 The Ruby Way 之本质。
关于作者
Hal Fulton 拥有 Mississippi 大学的两个计算机学位。在因为一些工作(主要是 IBM Austin)搬家到得克萨斯州 Austin 之前,他在地区技术院校教了四年计算机科学。他在各种形式的 UNIX 上工作过 15 年,包括 AIX,Solaris,和 Linux。他 1999 年接触了 Ruby,并且 2001 年开始撰写这本书的第一版,这是英语的第二本 Ruby 书。他参加过 6 此 Ruby 大会,并且在其中 4 次做过演讲。包括在 Karlsruhe, Germany 的第一次欧洲 Ruby 大会。他现在 Austin 的 Broadwing Communications,致力于大型数据仓库和相关通讯应用。他的日常工作使用 C++,Oracle,当然也包括 Ruby。
Hal 仍旧活跃于 Ruby 邮件列表和 IRC 频道中,并且有几个开发中的 Ruby 项目。他是 ACM 和 IEEE 计算机协会的成员之一。个人生活中,他喜欢音乐,读书,写作,艺术,和摄影。他是火星协会的会员之一,并且是一名太空爱好者,他希望在有生之年步入太空。他住在得克萨斯州的 Austin。
查看英文原文: What is the Ruby Way? - - - - - -
译者简介:董彬, NibiruTech 创始人之一,现致力于运用 Ruby on Rails 等高端技术和敏捷过程为客户提供项目定制和咨询服务。他曾效力于 IBM 中国开发中心,对于企业应用开发具有丰富的经验。个人爱好是户外运动和围棋。他的 blog 地址是: http://dongbin.javaeye.com/ 。
评论