分享

牛人点评Ruby语言十大令人喜爱的特点(1) - 51CTO.COM

 woshishenxiande 2011-03-16
    自从Rails框架问世后,Ruby一举成为了一个令不少人赞赏的编程语言。在这篇文章中,来自Merb与Rails核心开发团队的Yehuda Katz向我们分享了十大令人喜爱的Ruby语言特点。

     

    【51CTO精选译文】我每天都要用 Ruby 工作,久而久之,我现在真的喜欢上使用它了。(51CTO编者注:本文作者Yehuda Katz是Ruby on Rails核心开发团队的成员,以及Merb项目的主要推动者。)下面是一个列表,列出了我最喜欢的 Ruby 语言特点。一些特点显而易见,一些特点也存在于其他语言中。分享 Ruby 这些我喜欢的特点,并非是为了和其他语言进行比较和对比。

    51CTO编辑推荐:Ruby入门教程与技巧大全

    1. 动态类型

    静态类型语言也有很不错的功能,比如编译时验证和 IDE 支持。不过根据我的经验,动态类型对于项目启动真的有很大帮助,并且便于进行更改,尤其是在项目的早期到中期这些阶段。

    为了能够让我能够轻松地继续对象交换,我不需要为新对象创建正式的接口,这点让人很开心。

    2. Duck Typing(鸭子类型)

    这只是动态类型的一个有效的扩展。在 Ruby 中,预期能够对字符串对象进行操作的方法并不会检查 is_a?(String)。它们检查对象是否 respond_to?(:to_str),如果是,就接着调用对象的 to_str。与此类似,在 Ruby 中表示路径(Path)的对象能够实现一个 to_path 方法为提供路径重现(representation)。

    在 Rails 语言中,对于具有“模型”特性的对象,我们可以使用这样的技巧来实现对它们 respond_to?(:to_model) 的预期。如果这些对象能够为我们提供一个它们自身的“模型”重现,我们就能够在相关语境中支持任何类型。51CTO之前曾发布过有关Ruby中鸭子类型的介绍,可以参考一二。

    3. 令人叹为观止的模块

    Ruby 提供了一个与 Scala、Squeak 和 Perl 语言中“traits”类似的功能。事实上,Ruby 模块可以在运行时动态地址类等级中添加新元素。运行时可以动态地对 super 的使用继续评估以考虑所有添加的模块,这样就可以方便地按照所需多次地扩展超类功能,而且无需指定在类声明时确定super的加载地点。

    此外,Ruby 模块提供了生命周期钩子(hook)append_features 和 included,这样就可以使用模块来互相隔离扩展以及在特性包含的基础上动态的扩展类。

    4. 类主体不是专用的

    在 Ruby 中,类主体不是专用的语境。它们仅仅是一个对象类的自身指向点。如果你用过 Rails,你可能看到这样的代码:

            
    1. class Comment < ActiveRecord::Base  
    2.   validates_presence_of :post_id 
    3. end 

    validates_presence_of 看起来好像是语言的一项功能,但实际上它是 Comment 上调用的方法,而 Comment 由 ActiveRecord::Base 提供。

    该方法可以类中的执行任意代码(arbitrary code),包括创建新的方法,执行代码中其他内容,或者更新类实例变量。与必须在编译时运行的 Java 标注不同,Ruby 类主体能够考虑到运行时的信息,如动态提供的选项或其他代码的评估结果。

    5. 字符串求值(eval 功能)

    这可能是一个不同的想法。这里我不是指任意运行时字符串的求值,而是用于在 Ruby 程序启动过程中创建方法的字符串求值。

    这样就能够利用 Ruby 定义的结构(如 Rails 路径或 AOP 定义),并且能够将其编译到 Ruby 方法中。当然,也可以将其作为其他语言的附件(add-on)来实现,但在纯 Ruby 环境中实现这类功能是可能的。在很大程度上,它是一种自足执行(self-hosting)的一种语言。

    6. 区块和 Lambda 表达式

    我已经说过多次,这里再重复一次:我认为没有匿名 lambda 表达式的语言还没有足够强大到让我每天使用它。这些构造事实上非常常见,在 Ruby、JavaScript、Scala、Clojure 和 Lisp 中也存在。51CTO之前介绍过Ruby 1.9中的Lambda表达式,有兴趣的读者可以看看。

    利用它们,就能够实现看起来好像是语言功能的区块范围内的构造。最常见的使用示例是对文件的操作。在没有 lambda 的语言中,用户不得不在同一个语法范围(和他们最初打开的文件一致)中使用一段“确保”区块,以确保关闭了资源。

    在 Java 中:

            
    1. static void run(String in)   
    2. throws FileNotFoundException {  
    3.   File input = new File(in);  
    4.   String line; Scanner reader = null;  
    5.   try {  
    6.     reader = new Scanner(input);  
    7.     while(reader.hasNextLine()) {  
    8.       System.out.println(reader.nextLine());  
    9.     }  
    10.   } finally { reader.close(); }  

    Java 版的代码常常需要在 try 区块中包括 Scanner 的创建以保证其关闭。相反,让我们看看 Ruby 的代码:

            
    1. def run(input)  
    2.   File.open(input, "r"do |f|  
    3.     f.each_line {|line| puts line }  
    4.   end 
    5. end 

    由于区块的存在,我们可以省去在单个位置关闭文件的麻烦,将程序员错误减少到最小并且能够减少重复。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多