<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所包含的一些新特性。

      (本文內容選譯自該幻燈片:https://speakerdeck.com/shyouhei/whats-new-in-ruby-2-dot-0 )


     為什么有Ruby 2.0?

    • 因為我們在改變事物。
    • 我們渴望讓自己變得越來越快樂、健康、以及高產。
    • 不必畏懼。“擁抱變化。”

     Ruby 2.0有什么新鮮的?

      什么不是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來傳遞給方法。要為參數指定默認值,實現起來就很累贅,參見如下代碼)

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

      注意到代碼中錯誤的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注:雖然幻燈片里沒有寫,傳統的基于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現在默認把所有的輸入都視作UTF-8編碼。當然你也可以顯式地指定需要的編碼。

     Ruby 2.0的核心性能改進

      require的改進

    • 背景:今天,由于我們有了許多gems,啟動Ruby有時甚至需要一次require 128+個庫——這帶來了糟糕的性能問題。
    • 解決:require變得更快了(從計算復雜度的意義上來說)。
      • 若干技術被應用于減少多余的計算上。

      Backtrace惰性生成

    • 起初,backtraces只是字符串數組而已。
    • 每當拋出異常時,這些字符串就被自上而下地生成出來,即使在它們沒有實際用途的情況下。
      • 這導致了超乎尋常的低效,尤其是當你有1024+個stack frames時(這在Rails應用中很常見)。
    • 從Ruby 2.x開始,Thread::Backtrace被用來取代字符串。
      • 它們非常地輕量級。
    • 當你需要查看backtrace時,只需將它們轉換成字符串即可(調用#to_s)。

      Flonum類

    • 在64位平臺(如今早就爛大街了)上,指針,整型和浮點型數均是64位寬度的。
    • 在Ruby中,指針和整型均為C級別的register寄存器變量。而double卻是存儲在內存中的,如果我們能夠如操作指針一樣操作它們,將如何呢?
    • 問題:如何讓一個指針和一個double共存于一個union中?
    • 解決:一些技巧性的位移。

      Mort注:圖片懶得搬運了……請參見原幻燈片。

      GC(Garbage Collection)

    • Bitmap標志:以前,GC標志位存儲于每個對象中,但現在已經被轉移到了專用的內存頁中,以減少緩存的誤查詢(同時也更加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

      模塊前插

      有時候你想要給一個方法添加需要的安裝或拆解代碼,而相應的部分卻定義在別處。

    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__所在的目錄名。
    • Kernel#to_h:通用的Hash轉換方法。
    • Random類(1.9+):可重復的PRNG。
    • IO#wait_writable:等待直到可寫。
    • Refinements: 實驗性的。

      Mort注:更多關于Ruby 2.0核心特性的介紹,參考

     Ruby 2.0標準庫的改進

    • CGI
      • CGI已經為HTML5做好了一切準備。
    • net/http
      • 支持SNI(Server Name Indication)。
    • Zlib綁定
      • Zlib如今運行在解釋器的進程鎖之外。這意味著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版吧!

      也就是說,

    • 新的東西被加進來了。
    • 許多內部的東西得到了改進。
    • 即使你對你當前的環境充分自信,2.0.0仍然值得你擁有。

     Don’t be afraid. Use Ruby today!

      視頻:AKB48 - Ruby

    QQ群:WEB開發者官方群(515171538),驗證消息:10000
    微信群:加小編微信 849023636 邀請您加入,驗證消息:10000
    提示:更多精彩內容關注微信公眾號:全棧開發者中心(fsder-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>