Ruby 2.0 有哪些新特性?
本月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) # => [: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核心特性的介紹,參考
- http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-features
- http://www.infoq.com/news/2012/11/ruby-20-preview1
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
相關文章
- AngularJS 2.0會有哪些新特性?AngularJS
- Git 2.1 有哪些新特性?Git
- Chrome 60 Beta 有哪些新特性?Chrome
- Chrome 61 Beta有哪些新特性?Chrome
- Java9有哪些新特性?Java
- Django 2.0 新特性Django
- PHP 8 有哪些值得期待的新特性PHP
- C++ 2.0新特性C++
- Firebug 2.0新特性
- C# 2.0 新特性C#
- CameraX 1.1 有哪些新的特性發布?
- 〔譯〕TypeScript 2.0 的新特性TypeScript
- Entity Framework Core 2.0 新特性Framework
- HTTP----HTTP2.0新特性HTTP
- XPath 2.0 的新特性 (轉)
- Chrome 58測試版釋出,有哪些新特性?Chrome
- XSLT 2.0 的新特性 (轉)
- Ruby 札記 - 淺嘗 Ruby 特性
- 淺談RxJava與2.0的新特性RxJava
- 物件導向有哪些特性物件
- Flink 1.11.0 釋出,有哪些值得關注的新特性?
- 谷歌的Android Q到底有哪些新特性及變更?谷歌Android
- C# 11 都有哪些新特性?C#
- PHP 7.4 新特性 —— 箭頭函式 2.0PHP函式
- BSN開放聯盟鏈“中移鏈”2.0瀏覽器提供了哪些新特性?瀏覽器
- JDK8到JDK17有哪些吸引人的新特性?JDK
- Ruby 2.0 Preview 1釋出View
- 創新觸手可及: WebSphere CloudBurst V2.0 新特性WebCloud
- 什麼是Docker?Docke有哪些特性?Docker
- 成功的CRM需要擁有哪些特性
- HTTP/2有哪些值得期待的特性HTTP
- 新聞類APP軟體開發有哪些特性?北京銳智互動APP
- 即將釋出的ionic4有哪些激動人心的新特性
- Rails 5 有什麼新特性?AI
- C++2.0——語言新特性之Variadic TemplatesC++
- Spring Boot 2.0 新特性(二):新增事件ApplicationStartedEventSpring Boot事件APPdev
- 直流共模電感的特性有哪些
- 輕量級前端架構有哪些特性?前端架構