<li id="2aw4k"></li>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
    <center id="2aw4k"><small id="2aw4k"></small></center><center id="2aw4k"><small id="2aw4k"></small></center>
    首页»RubyOnRails»Ruby 2.0 有哪些新特性?

    Ruby 2.0 有哪些新特性?

    来源:soimort 发布时间:2013-02-25 阅读次数:

      本月24日,Ruby 2.0终于就要发布了。

      Ruby核心团队的卜部昌平桑昨天在一个内部学习会上的presentation,介绍了Ruby 2.0所包含的一些新特性。

      (本?#21738;?#23481;选译自该幻灯片:https://speakerdeck.com/shyouhei/whats-new-in-ruby-2-dot-0 )


     为什么有Ruby 2.0?

    • 因为我们在改变事物。
    • 我们渴望让自己变得越来越快乐、健康、以及高产。
    • 不必畏惧。“拥抱变化。”

     Ruby 2.0有什么新鲜?#27169;?/h2>

      什么不是Ruby 2中的新鲜货

    • 几乎所有的东西。
    • “100%后向兼容”,matz如是说。
      • 在现实中……
    • (举个例子来说)Rails仍然能完好运行如初。

      也就是说,

    • 新的东西被加进来了。
    • 许多内部的东西得到了改进。

     Ruby 2.0的新句法

      关键字参数(Keyword arguments)

      下面的代码在1.x中能够正常工作:

    obj.method "with", :lots => "of",
                       :args => "in",
                       :hash => "form"

      但是,问题出在哪呢?

      问题是在定义该方法的时候: (Mort注:在Ruby 1.x中,只能将多个带符号名称的参数作为一个Hash?#21019;?#36882;给方法。要为参数指定默?#29616;擔?#23454;现起来就很累赘,参见如下代码)

    def obj.method(arg, hash)
      lots = Hash[:lots] || "default"
      args = Hash[:args] || "another"
      hand = Hash[:by hand] || "annoying"
      ...
    end

      注意到代码?#20889;?#35823;的Hash[:by hand]——手写代码是错误产生的根源!

      从2.0开始,Ruby将引入关键字参数:

    def obj.method(a, b = 1, c: 1, d: 2)

      其中a为固定参数,b为可选参数,c、d则为关键字参数。这样,局部变量a、b、c和d都将被恰当地赋值。

      在调用函数时,原有的调用方式无需更改。

      Mort注?#26680;?#28982;幻灯片里没有写,传统的基于Hash参数的调用方法是这个样子的

    obj.method("foo", :c => 2, :d => 3)

      现在Ruby 2.0同时也支持直接采用关键字参数的调用方法:(Python程序员一定会觉得这种语法更亲切)

    obj.method("foo", c: 2, d: 3)

      更详细的示例,可以参考这里:

      http://brainspec.com/blog/2012/10/08/keyword-arguments-ruby-2-0/

      其他细微的句法改进

    • 引入了符号数组字面值%i和%I。
    <code>%i(foo bar baz) # =&gt; [:foo, :bar, :baz] </code>
    • Ruby现在默?#20064;?#25152;有的输入都视作UTF-8编码。当然你也可以显式地指定需要的编码。

     Ruby 2.0的核心性能改进

      require的改进

    • 背景:今天,由于我们有了许多gems,启动Ruby有时甚至需要一次require 128+个库——这带来了糟糕的性能问题。
    • 解决:require变得更快了(从计算复杂度的意义上来说)。
      • 若干技术被应用于减少多余的计算上。

      Backtrace惰性生成

    • 起初,backtraces只是字符串数组而已。
    • ?#24247;?#25243;出异常时,这些字符串就被自上而下地生成出来,即使在它们没有实际用途的情况下。
      • 这导致了超乎寻常的低效,尤其是当你有1024+个stack frames时(这在Rails应用中很常见)。
    • 从Ruby 2.x开始,Thread::Backtrace被用来取代字符串。
      • 它们非常地轻量级。
    • 当你需要查看backtrace时,只需将它们转换成字符串即可(调用#to_s)。

      Flonum类

    • 在64位?#25945;ǎ?#22914;今早就烂大街了)上,指针,整型和浮点型数均是64位宽度的。
    • 在Ruby中,指针和整?#36884;?#20026;C级别的register寄存器变量。而double却是存储在内存中?#27169;?#22914;果我们能够如操作指针一样操作它们,将如?#25991;兀?/li>
    • 问题:如何让一个指针和一个double共存于一个union中?
    • 解决:一些技巧性的位移。

      Mort注?#21644;计?#25042;得搬运了……请参见原幻灯片。

      GC(Garbage Collection)

    • Bitmap标志:以前,GC标志位存储于每个对象中,但现在已经被转移到了专用?#21738;?#23384;页中,以减少缓存的误查询(同时也更加CoW (Copy-on-Write)友好)。
    • 非递归标志:标志函数如今避免了机器栈溢出的风险。
    • 惰性清理(从1.9.3起):清理器只有在必须的地方才进行收集(减少了stop时间)。

     Ruby 2.0的新核心特性:#1 调试工具

      DTrace支持

      TracePoint支持

      GC stats

     Ruby 2.0的新核心特性:#2 核心库

      细粒度的异步中断处理

      Ruby的执行有时会因为各种原因而中断,例如,超时。

      Ruby 2.0提供了细粒度的异步中断处理方案:

    Thread.async_interrupt_timing Timeout::Error => :defer do
      timeout(rand()) do
        begin
          Thread.async_interrupt_timing Timeout::Error => :immediate do
            setup
            handle
            ...
          end
        ensure
          teardown
        end
      end
    end

      模块前插

      有时候你想要给一个方法添?#26377;?#35201;的安装或拆解代码,而相应的部分却定义在别处。

    module ActiveRecordHelper
      def save
        ???
      end
    end

      该如何去做呢?在Ruby 2.0中,你可以:

    class Foo < AR::Base
      prepend AR::Helper
    
      def save
        bar
      end
    end
    
    module AR::Helper
      def save
        foo
        super
        baz
      end
    end
    
    Foo.new.save

      这避开了Rails中的所谓“别名方法链(alias method chain)”的困扰。AMC什么的已经不再必要了。

      惰性枚举器

      Ruby的foo.bar.baz. ...风格(所谓的“流水作业”)有时会传递许多并不必要的临时对象,而这些理论上都可以通过惰性求值来避免。

    File.open(path) {|fp|
        fp.each_line. \
        select {|line| # 生成了临时数组
        /regexp/ =~ line
        }. \
        each_with_index.map {|line, no| # 生成了临时数组
        sprintf("%d: %s\n", no, line)
        }. \
        first(10).each {|str| # 生成了临时数组
            puts(str)
        }
    }
    File.open(path) {|fp|
        fp.each_line.lazy \
        select {|line| # 没有临时数组产生
        /regexp/ =~ line
        }. \
        each_with_index.map {|line, no| # 没有临时数组产生
        sprintf("%d: %s\n", no, line)
        }. \
        first(10).each {|str| # 没有临时数组产生
            puts(str)
        }
    } # 甚至在到达EOF之前都不读取数据

      一个有趣的应用实例:无穷枚举器。

    # Leibniz formula for π
    (0..Float::INFINITY).lazy.map {|i|
        ((-1) ** i) / (2*i + 1).to_f
    }.take(65536).reduce(:+) * 4

      其他的新方法

    • Kernel.__dir__:获取__FILE__所在?#21738;?#24405;名。
    • Kernel#to_h?#21644;?#29992;的Hash转换方法。
    • Random类(1.9+):可重复的PRNG。
    • IO#wait_writable:等待直到可写。
    • Refinements: 实验性的。

      Mort注:更多关于Ruby 2.0核心特性的介绍,参考

     Ruby 2.0标准库的改进

    • CGI
      • CGI已经为HTML5做好了一切准?#28014;?/li>
    • net/http
      • 支持SNI(Server Name Indication)。
    • Zlib绑定
      • Zlib如今运?#24615;?#35299;释器的进程锁之外。这意味着zlib在多线程的情形下运行速度将更快。
    • 更新的stdlibs(标准库)
      • Rubygems 2.0.0
      • JSON 1.7.7
      • Rake 0.9.5
      • Rdoc 4.0
      • 以及其它(REXML,yaml,openssl……)

     总结

      什么不是Ruby 2中的新鲜货

    • 几乎所有的东西!
    • “100%后向兼容”,matz如是说。
    • (举个例子来说)Rails仍然能完好运行如初。
    • 不必畏惧!开始使用2.0.0版?#26705;?/li>

      也就是说,

    • 新的东西被加进来了。
    • 许多内部的东西得到了改进。
    • 即使你?#38405;?#24403;前的环境充分自信,2.0.0仍然值得你拥有。

     Don’t be afraid. Use Ruby today!

      视频:AKB48 - Ruby

    QQ群:WEB开发者官方群(515171538),验证消息:10000
    微信群:?#26377;?#32534;微信 849023636 邀请您加入,验证消息:10000
    提示:更多精彩内容关注微信公众号:全栈开发者中?#27169;╢sder-com)
    网友评论(共2条评论) 正在载入评论......
    理智评论文明上网,拒绝恶意谩骂 发表评论 / 共2条评论
    登录会员中心
    大乐透彩票预测
    <li id="2aw4k"></li>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
    <center id="2aw4k"><small id="2aw4k"></small></center><center id="2aw4k"><small id="2aw4k"></small></center>
    <li id="2aw4k"></li>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
  • <div id="2aw4k"><tr id="2aw4k"></tr></div>
    <center id="2aw4k"><small id="2aw4k"></small></center><center id="2aw4k"><small id="2aw4k"></small></center>