掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流
本月24日(也就是明天)Ruby 2.0終于就要發(fā)布了。

成都創(chuàng)新互聯(lián)公司主營進賢網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,成都App制作,進賢h5成都小程序開發(fā)搭建,進賢網(wǎng)站營銷推廣歡迎進賢等地區(qū)企業(yè)咨詢
Ruby核心團隊的卜部昌平桑昨天在一個內部學習會上的presentation,介紹了Ruby 2.0所包含的一些新特性。
(本文內容選譯自該幻燈片。)
為什么有Ruby 2.0?
因為我們在改變事物。
我們渴望讓自己變得越來越快樂、健康、以及高產(chǎn)。
不必畏懼?!皳肀ё兓!?/p>
Ruby 2.0有什么新鮮的?
什么不是Ruby 2中的新鮮貨
幾乎所有的東西。
“100%后向兼容”,matz如是說。
(舉個例子來說)Rails仍然能完好運行如初。
也就是說,
新的東西被加進來了。
許多內部的東西得到了改進。
Ruby 2.0的新句法
關鍵字參數(shù)(Keyword arguments)
下面的代碼在1.x中能夠正常工作:
- obj.method "with", :lots => "of",
- :args => "in",
- :hash => "form"
但是,問題出在哪呢?
問題是在定義該方法的時候: (Mort注:在Ruby 1.x中,只能將多個帶符號名稱的參數(shù)作為一個Hash來傳遞給方法。要為參數(shù)指定默認值,實現(xiàn)起來就很累贅,參見如下代碼)
- def obj.method(arg, hash)
- lots = Hash[:lots] || "default"
- args = Hash[:args] || "another"
- hand = Hash[:by hand] || "annoying"
- ...
- end
注意到代碼中錯誤的Hash[:by hand]——手寫代碼是錯誤產(chǎn)生的根源!
從2.0開始,Ruby將引入關鍵字參數(shù):
- def obj.method(a, b = 1, c: 1, d: 2)
其中a為固定參數(shù),b為可選參數(shù),c、d則為關鍵字參數(shù)。這樣,局部變量a、b、c和d都將被恰當?shù)刭x值。
在調用函數(shù)時,原有的調用方式無需更改。
Mort注:雖然幻燈片里沒有寫,傳統(tǒng)的基于Hash參數(shù)的調用方法是這個樣子的
- obj.method("foo", :c => 2, :d => 3)
現(xiàn)在Ruby 2.0同時也支持直接采用關鍵字參數(shù)的調用方法:(Python程序員一定會覺得這種語法更親切)
- obj.method("foo", c: 2, d: 3)
更詳細的示例,可以參考這里:
http://brainspec.com/blog/2012/10/08/keyword-arguments-ruby-2-0/
- %i(foo bar baz) # => [:foo, :bar, :baz]
Ruby 2.0的核心性能改進
require的改進
背景:今天,由于我們有了許多gems,啟動Ruby有時甚至需要一次require 128+個庫——這帶來了糟糕的性能問題。
解決:require變得更快了(從計算復雜度的意義上來說)。
Backtrace惰性生成
起初,backtraces只是字符串數(shù)組而已。
每當拋出異常時,這些字符串就被自上而下地生成出來,即使在它們沒有實際用途的情況下。
從Ruby 2.x開始,Thread::Backtrace被用來取代字符串。
當你需要查看backtrace時,只需將它們轉換成字符串即可(調用#to_s)。
Flonum類
在64位平臺(如今早就爛大街了)上,指針,整型和浮點型數(shù)均是64位寬度的。
在Ruby中,指針和整型均為C級別的register寄存器變量。而double卻是存儲在內存中的,如果我們能夠如操作指針一樣操作它們,將如何呢?
問題:如何讓一個指針和一個double共存于一個union中?
解決:一些技巧性的位移。
Mort注:圖片懶得搬運了……請參見原幻燈片。
GC(Garbage Collection)
Bitmap標志:以前,GC標志位存儲于每個對象中,但現(xiàn)在已經(jīng)被轉移到了專用的內存頁中,以減少緩存的誤查詢(同時也更加CoW (Copy-on-Write)友好)。
非遞歸標志:標志函數(shù)如今避免了機器棧溢出的風險。
惰性清理(從1.9.3起):清理器只有在必須的地方才進行收集(減少了stop時間)。
Ruby 2.0的新核心特性:#1 調試工具
DTrace支持
TracePoint支持
GC stats
Ruby 2.0的新核心特性:#2 核心庫
細粒度的異步中斷處理
Ruby的執(zhí)行有時會因為各種原因而中斷,例如,超時。
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什么的已經(jīng)不再必要了。
惰性枚舉器
Ruby的foo.bar.baz. ...風格(所謂的“流水作業(yè)”)有時會傳遞許多并不必要的臨時對象,而這些理論上都可以通過惰性求值來避免。
- File.open(path) {|fp|
- fp.each_line. \
- select {|line| # 生成了臨時數(shù)組
- /regexp/ =~ line
- }. \
- each_with_index.map {|line, no| # 生成了臨時數(shù)組
- sprintf("%d: %s\n", no, line)
- }. \
- first(10).each {|str| # 生成了臨時數(shù)組
- puts(str)
- }
- }
- File.open(path) {|fp|
- fp.each_line.lazy \
- select {|line| # 沒有臨時數(shù)組產(chǎn)生
- /regexp/ =~ line
- }. \
- each_with_index.map {|line, no| # 沒有臨時數(shù)組產(chǎn)生
- sprintf("%d: %s\n", no, line)
- }. \
- first(10).each {|str| # 沒有臨時數(shù)組產(chǎn)生
- puts(str)
- }
- } # 甚至在到達EOF之前都不讀取數(shù)據(jù)
一個有趣的應用實例:無窮枚舉器。
- # Leibniz formula for π
- (0..Float::INFINITY).lazy.map {|i|
- ((-1) ** i) / (2*i + 1).to_f
- }.take(65536).reduce(:+) * 4
Mort注:更多關于Ruby 2.0核心特性的介紹,參考
Ruby 2.0標準庫的改進
總結
什么不是Ruby 2中的新鮮貨
幾乎所有的東西!
“100%后向兼容”,matz如是說。
(舉個例子來說)Rails仍然能完好運行如初。
不必畏懼!開始使用2.0.0版吧!
也就是說,
新的東西被加進來了。
許多內部的東西得到了改進。
即使你對你當前的環(huán)境充分自信,2.0.0仍然值得你擁有。
Don’t be afraid. Use Ruby today!
視頻:AKB48 - Ruby
原文鏈接:http://www.soimort.org/posts/140/

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流