37个我爱Ruby的理由
原著: http://hypermetrics.com/ruby.html
翻译:liubin http://www.ruby-cn.org/
一切权利归原作者所有,转载请保留。
2004/12/3
我不打算浪费时间来谈论Ruby的历史,如果你没有听说过它,你可以去它的主页看看www.ruby-lang.org,或者去它的新闻组comp.lang.ruby。如果你知道Ruby,我将讲述我为什么会喜爱它。(你也可能去我的Ruby主页或者个人主页看看)
-
它是面向对象的。 这表示什么意义呢? 如果问10个程序员,你也许会得到12种结果,你有你的看法,我不会试图去改变你的看法。但是有一点,Ruby提供了对数据和方法的封装,允许类的继承, 对象的多态。不像其它语言(C++,Perl等),Ruby从设计的时候开始就是一种面向对象的语言。
-
它是纯面向对象的语言。难 道是我多余?不是这样的,之所以这么说,因为Ruby中一切都是对象,包括原始数据类型(primitive data types),比如字符串,整型,都表示的是一个对象,而不需要Java那样提供包装类(wrapper classes)。另外,甚至是常量,也会被当作对象来处理,所以一个方法的接收者,可以是一个数字常量。
-
它是动态语言。 对于只熟悉像C++,Java这样静态语言的人来说,这是一个重大的概念上的差别。动态意味着方法和变量可以在运行时候添加和重定义。它减少了像C语言那样的条件编译(#ifdef),而且容易实现反射API(reflection API)。动态性使得程序能自我感知(self-aware),比如运行时类型信息,检测丢失的方法,用来检测增加方法的钩子等。在这些方面Ruby和Lisp和Smalltalk都有一些关系。
-
它是一种解释执行的语言。这 是一个负杂的问题,值得重点解释一下,也许这个特点会因为性能的原因而引起从优点变为缺点的争论。对于此,我有几点见解:1.第一:快速开发循环是一个巨 大的好处,这要得意于Ruby的解释执行。2.多慢才叫慢呢?在说它慢之前先定一个慢的基准。3.也许有人要批评我了,但我还要说:处理器每年都在变得原 来越快。4.如果你真的很在意你的速度,你可以用C开发一部分你的代码。5.最后,从某种意义上说,这是一个还在争论中的问题,没有一个语言天生就是解释 型的,世界上没有哪个法律进制开发一个Ruby编译器出来。
-
它理解正则表达式。 很 多年之前,正则表达式只是用在UNIX的工具如grep或者sed中,或者在vi中进行一些一定的查找-替换等。Perl的出现解决了这些问题,而现在, Ruby同样也能做到这些。越来越多得人认识到了这种字符串和文本处理技术的难以置信的能力,如果你对此表示怀疑,那么请去看一下 Jeffrey Friedl的书Mastering Regular Expressions,然后,你就应该不会有什么怀疑了。
-
它是多平台的。 Ruby可以运行在Linux,UNIX,Windows,BeOS,甚至MS-DOS。如果我没记错,甚至还有一个Amiga 版本的
-
它是派生来的。 这 是一件好事情吗?抛去书本上的知识,它是有用的。牛顿曾说过“我如果看得比别人远,那是因为我站在巨人的肩膀上”。Ruby同样也是站在巨人的肩膀上,它 借鉴了Smalltalk, CLU, Lisp, C, C++, Perl, Kornshell等的优点。在我看来它的原则包括:1.不要重复制造轮子。2.不要修补没有损坏的东西。3.最后一个也是比较特别的,它能平衡 (Leverage )你已有的知识。你了解UNIX的文件和管道,没关系,你可以在Ruby中继续用,你用了两年的时间学习了printf 指示符,不必担心,Ruby中你也可以使用printf。你知道Perl的正则表达式处理,那么你也就学会了Ruby中的正则表达式。
-
它是创新的。 是 不是觉得这个和第七条矛盾了?也许是有一部分矛盾,每个硬币都有两面。一些Ruby的特点都是创新的东西,比如非常有用的Mix-in,也许这个特点会被 后来的语言借鉴。(注:一位读者指出Lisp早在1979年就有mix-in了,这是我的疏忽;我应该找个更好的例子,并且能确信它。)
-
它是非常高层次的语言。(Very High-Level Language :VHLL) 这 是一个容易引起争论的话题,因为这个术语还没有广泛使用。而且它的意思比起OOP来说还是有讨论余地的。我这么说,指的是Ruby能支持复杂的结构和这些 结构的负杂的操作,而需要的指令非常少,这与最小努力原则(Principle of Least Effort)一致。
-
它有一个灵巧的垃圾收集器。 像malloc和free 这样的例程已经是昨天的恶梦了,你不需要什么回收内存的操作,甚至是调用垃圾收集器。
-
它是脚本语言。 不要因为此就认为它不够强大,它不是一个玩具。它是完全成熟的语言,用它能轻松的完成传统的脚本操作,比如运行外部程序,检查系统资源,使用管道,捕获输出等等。
-
它是通用的。 Kornshell做的东西它也可以做,C语言做的东西它也可以做的很好。你可以用它写一个只运行一次的只有10行的程序,或者对一些遗留程序进行包装,你想写个web server,或者一个CGI,都可以用Ruby来写。
-
它是多线程的。 Y你可以用一些简单的API来写多线程程序,甚至在MS-DOS上都可以。
-
它是open source的。 你想看它的源代码吗?可以,你也可以提交补丁,参加广泛的社区,包括它的创造者。
-
它是直觉得。 Ruby的学习曲线比较低,而如果你翻过了一个坎,你开始“猜测”事情是怎么工作的,而且你的猜测很多时候都是正确的。Ruby坚持最小惊讶( Least Astonishment)的原则。
-
它有异常机制。 像Java和 C++一样, Ruby 中也有异常机制,这意味着你不必因为返回值而将代码弄得凌乱不堪,很少的嵌套if语句,很少的意大利面条似的逻辑,更好的错误处理。
-
它有一个高级的数组类:Array。 Ruby 中数组都是动态的,你不必像pascal那样在声明它的大小,也不必像C,C++那样为它分配内存。它们是对象,所以你不必关心它们的长度,实际上你不能 "走到末尾(walk off the end)"。这个类提供了各种方法,使得你能够根据索引,根据元素来访问数组内容,也可以反向处理数组。你也可以用数作作为set,队列,堆栈等。如果你 想用查找表,可以用哈希结构。
-
它是可以扩展的。 你可以用C或者Ruby来编写外部库(external libraries),同样,你也可以修改已有的类和对象。
-
鼓励文档编程(literate programming)。 你可以在Ruby程序中嵌入注释或者文档,这些文档可以用Ruby的文档工具提取和处理。(真正的文档编程者可能认为这是必须的基本东西吧)
-
创造性的使用标点符号和大写字母。 比 如一个方法返回一个boolean型(Ruby中并没有这种说法),那么一般这个方法最后都以问号结尾,如果一个方法要修改接收者本身,或者具有破坏性, 则用一个感叹号结尾,简单,直觉。所有常量,包括类名,都以大写字母开头,所有对象属性以@符号开头。这有匈牙利命名法的实用性,但是没有视觉上的丑陋 性。
-
Reserved words aren't.It's perfectly allowable to use an identifier that is a so-called "reserved word" as long as the parser doesn't perceive an amibiguity. This is a breath of fresh air.(能用保留字作为变量吗?没看太懂。)
-
支持迭代器。 这使得你可以给一个数组,list,tree等对象传递一个块,然后对它们的每个元素进行block调用。这个技术值得深入学习。
-
它的安全性。 Ruby借鉴了Perl中基于$SAFE变量的分层控制机制 。这对于CGI程序来说非常有用,可以防止人们攻击web服务器。
-
Ruby中没有指针。 像 Java一样,和C++不同,Ruby中没有指针的概念,所以免除了关于指针语法和调试的头疼。当然,这也意味着最底层的程序开发将会很困难,比如访问一 个设备的控制状态寄存器;但是,我们可以用一个C库来调用。(像C语言程序员有时候要使用汇编语言一样,Ruby程序员有时候也要使用C语言来完成一定的 任务)
-
它使得人们专注于细节。 Ruby中有很多同义词和别名,你也许不记得字符串或数组的长度是size还是length,没关系,它们任何一个都可以工作。对于Range来说,你可以使用begin 和end 或者使用 first 和 last,它们也都工作。你想拼写indices,结果写成了indexes,没关系,这两个都一样。
-
非常灵活的语法。 方法调用时候括号可以省略,参数之间只需用逗号分割。类似Perl风格的数组定义可以让你不用全部使用引号和逗号定义一个字符串的数组。关键字return可以生路。
-
丰富的库函数。 Ruby提供了线程,socket,有限对象持久化,CGI,服务器端可执行的,数据库等其它库函数,还有对Tk的支持等。还有很多其它的库函数。
-
本身自带调试器(debugger)。 在完美的世界中,我们才不需要调试器,但是这个世界不是完美的。
-
交互式执行。 可以用Ruby像Kornshell那样执行。 (这可能是本页最具争论的一点,我不得不承认,Ruby真的不是一个很好的shell。但我仍然坚持,基于Ruby的shell是一个不错的主意。)
-
它是简明的。 不像Pascal那样要求if后面跟着then,while后面跟着do 。变量不需要声明,它们不需要类型。返回类型不必指定,关键字return 可以省略,它将返回最后一个表达式的值。另一方面,它也不像Perl或者C那样复杂难懂。
-
它是面向表达式的(expression-oriented)。 你可以轻易的使用 x = if a<0 then b else c 这样的表达式。
-
语法砂糖(syntax sugar)。 (像Mary Poppins解释:一勺语法的糖能使语义被接受) 。如果你想对数组x进行迭代,可以用for a in x。你也可以用a+=b代替a=a+b,这都行。很多操作符其实在Ruby中都是方法,这些方法的名字比较直观,短小,有着便利的语法。
-
它支持操作符重载。 如果我没有记错的话,早在很久之前的SNOBOL就提供了这个功能,但是直到C++它才变得流行。虽然它可能乱用而出错,但是这仍是一个非常不错的优点。另外Ruby自动定义操作符的赋值版本,比如,如果你重定义了+,那么,你同时得到了一个+=操作符。
-
支持无限精度的数字。 有人会关心 short, int, long吗,只需要使用 Bignum就行了,你可以轻松的实现365的阶乘。
-
有幂操作符。 在 很久以前,我们在BASIC和FORTRAN中使用它,然而当我们学习Pascal和C之后,我们才认识到这个操作符有多差劲。(我们被告知自己连它是怎 么工作的都不知道-它使用了对数,迭代了吗,效率如何?),但是,我们真的关系这些吗?如果是,我们可以重写这个方法,否则,Ruby有非常好的**操作 符可以用。
-
强大的字符串处理。 If如果你想查找,判断,格式化,trim,定界(delimit),interpose,tokenize,你可以自己选择随便用哪一个来得到你想要的结果。
-
规则很少引起异常。 Ruby的语法和语义比其它语言有条理,每种语言都有独特的一面,每条规则都会有异常发生,但是Ruby规则引起的异常就少的多了。
译者注:
第21条:看不太懂,难道是因为现在地版本太新了,老版本可能有这个特点?
第34条例子如下:
irb(main):019:0> a=1 => 1 irb(main):020:0> b=1 => 1 irb(main):021:0> 365.times{ a,b=a*b,b+1} => 365 irb(main):022:0> a => 25104128675558732292929443748812027705165520269876079766872595193901106138220 93741966601800900025416937617231436098232866070807112336997985344536791065387238 35997043555327409376780914914294408643160469250745101348470255460140980059079655 41041195496105311886173373435145517193282760847755882291690213539123479186274701 51939680850494072260703300124632839880055048742799987669041697343786107818534466 79668715110496538881301368361990105291800561258445494886486176829158263475641489 90984138067809999604687488146734837340699359838791124995957584538873616661533093 25355125684505604638873812970295138115186141368892298651000544094394301469924411 25557552791407604927642537402504103910564219790032896000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000 irb(main):023:0> b => 366 irb(main):024:0> |
呃。。。。21条应该是说Ruby没有保留字困扰,可以用保留字作为变量。