由 naruse 發表於 2019-12-25
翻譯: Juanito Fatas
我們很高興宣佈 2.7.0 發佈了。
本版帶有許多新功能及效能提升,主要有:
- 模式匹配
- REPL 改進
- GC 壓縮
- 分離依序參數和關鍵字參數
模式匹配 [實驗性質]
引入了實驗性質、在函數式程式語言廣泛使用的功能,模式匹配。見 [Feature #14912]。
模式匹配可以遍歷傳入的物件,如果找到匹配的模式就賦值給指定的變數。
require "json"
json = <<END
{
"name": "Alice",
"age": 30,
"children": [{ "name": "Bob", "age": 2 }]
}
END
case JSON.parse(json, symbolize_names: true)
in {name: "Alice", children: [{name: "Bob", age: age}]}
p age #=> 2
end
進一步了解請參考 Ruby 2.7 的新功能:模式匹配。
REPL 改進
irb
,內建的互動環境(REPL Read-Eval-Print-Loop),透過純 Ruby 所實現的 relin
和與 readline
相容的函式庫現支持多行編輯。irb
整合了 rdoc,可以顯示任何一個類別、模組、方法之間的引用關係。
[Feature #14683]、
[Feature #14787]、
[Feature #14918]。
除此之外,Binding#irb
所顯示的原始碼行號與查詢結果現在以彩色顯示。
Compaction GC
本版引入了 Compaction GC,可以整理零碎的記憶體空間。
由某些多線程的 Ruby 程式所引起的零碎記憶體空間,導致記憶體用量大增及速度變慢。
新增了 GC.compact
方法用來壓縮堆疊(heap)。這個方法壓縮了堆疊上正在使用的物件,進而使用更少的記憶體分頁,使堆疊對寫入式複製(CoW, copy-on-write)更加友好。
[Feature #15626]
分離依序參數和關鍵字參數
依序參數與關鍵字參數之間的自動轉換已經棄用,將在 Ruby 3 正式移除。 [Feature #14183]
詳見文章「Separation of positional and keyword arguments in Ruby 3.0」。
以下是改動的內容:
-
當一個接受參數的方法,呼叫時傳入的最後一個參數為 Hash,但沒有傳入所須的關鍵字參數,則會出現警告訊息。 要繼續將 Hash 作為關鍵字使用的話,請使用 double splat 運算子來確保程式可在 Ruby 3 正在作動並避免警告訊息。
def foo(key: 42); end; foo({key: 42}) # warned def foo(**kw); end; foo({key: 42}) # warned def foo(key: 42); end; foo(**{key: 42}) # OK def foo(**kw); end; foo(**{key: 42}) # OK
-
當接受關鍵字參數的方法傳入關鍵字,但沒有傳入足夠的依序參數時,關鍵字會被視作最後一個依序參數並出現警告訊息。請用 Hash 傳入參數而不是關鍵字確保程式可在 Ruby 3 正在作動並避免警告訊息。
def foo(h, **kw); end; foo(key: 42) # warned def foo(h, key: 42); end; foo(key: 42) # warned def foo(h, **kw); end; foo({key: 42}) # OK def foo(h, key: 42); end; foo({key: 42}) # OK
-
當方法接受特定關鍵字,但不接受 keyword splat,傳入一個有符號及非符號為鍵的 Hash 或 keyword splat 時,Hash 仍會被分解並報一個警告訊息。請分別傳入 Hash 以確保程式可在 Ruby 3 正常作動。
def foo(h={}, key: 42); end; foo("key" => 43, key: 42) # warned def foo(h={}, key: 42); end; foo({"key" => 43, key: 42}) # warned def foo(h={}, key: 42); end; foo({"key" => 43}, key: 42) # OK
-
若方法不接受關鍵字但呼叫時傳入關鍵字,則關鍵字會被依序視為 Hash 且不會出警告訊息。此行為在 Ruby 3 會繼續作動。
def foo(opt={}); end; foo( key: 42 ) # OK
-
方法接受任意關鍵字時,可以使用非符號作為關鍵字。 [Feature #14183]
def foo(**kw); p kw; end; foo("str" => 1) #=> {"str"=>1}
-
可以用
**nil
將方法標記為不接受任何關鍵字。用關鍵字呼叫這樣的方法會報一個 ArgumentError 錯誤。 [Feature #14183]def foo(h, **nil); end; foo(key: 1) # ArgumentError def foo(h, **nil); end; foo(**{key: 1}) # ArgumentError def foo(h, **nil); end; foo("str" => 1) # ArgumentError def foo(h, **nil); end; foo({key: 1}) # OK def foo(h, **nil); end; foo({"str" => 1}) # OK
-
給一個不接受關鍵字的方法傳入空的 keyword splat 時,參數不再視為空 Hsah。當空 Hash 是一個必要的參數時,則會報一個警告訊息。請移除 double splat 來繼續傳入一個依序的 Hash。 [Feature #14183]
h = {}; def foo(*a) a end; foo(**h) # [] h = {}; def foo(a) a end; foo(**h) # {} and warning h = {}; def foo(*a) a end; foo(h) # [{}] h = {}; def foo(a) a end; foo(h) # {}
如想不要顯示警告訊息,請使用命令行選項 -W:no-deprecated
,或是添加 Warning[:deprecated] = false
這行程式碼。
其他新功能
-
引入了基於數字的區塊參數。 [Feature #4475]
-
引入了實驗性質的無起始範圍,可能不像無終止範圍實用,但在實作 DSL 的場景很有用。 [Feature #14799]
ary[..3] # identical to ary[0..3] rel.where(sales: ..100)
-
新增
Enumerable#tally
,可以算出元素出現的次數["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
-
現在可從
self
呼叫私有方法 [Feature #11297]、 [Feature #16123]def foo end private :foo self.foo
-
新增
Enumerator::Lazy#eager
。從惰性求值的迭代器上產生一般的迭代器。 [Feature #15901]a = %w(foo bar baz) e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager p e.class #=> Enumerator p e.map {|x| x + "?" } #=> ["FOO!?", "BAR!?", "BAZ!?"]
效能改進
-
JIT [實驗性質]
-
當優化條件不成立時,經 JIT 編譯的程式碼將會重編成優化程度較低的程式碼。
-
方法若為純方法,則進行內聯優化。這個優化是實驗性質的,目前許多方法均不是純方法。
-
--jit-min-calls
的預設值從 5 改為 10,000。 -
--jit-max-cache
的預設值從 1,000 改為 100。
-
-
改變了 Fiber 的快取策略並提昇了建立 Fiber 的速度 GH-2224
-
Module#name
、true.to_s
、false.to_s
以及nil.to_s
現在永遠回傳已經凍結的字串。同一個物件會永遠回傳相同的字串。 [實驗性質] [Feature #16150] -
改善了
CGI.escapeHTML
的效能 GH-2226 -
改善了 Monitor 與 MonitorMixin 的效能 [Feature #16255]
-
改善了(自 Ruby 1.9 以來的)Per-call-site 的方法快取命中率,從 89% 提昇至 94%。 見 GH-2583
-
RubyVM::InstructionSequence#to_binary
方法會產生執行檔,減少了執行檔的大小。 [Feature #16163]
其他自 2.6 以來的變更
- 更新了某些標準函式庫
- Bundler 2.1.2 (發布記)
- RubyGems 3.1.2
- (3.1.0 的發布記)
- (3.1.1 的發布記)
- (3.1.2 的發布記)
- Racc 1.4.15
- CSV 3.1.2 (NEWS)
- REXML 3.2.3 (NEWS)
- RSS 0.2.8 (NEWS)
- StringScanner 1.0.3
- 也更新了一些沒有版本號的函式庫
- 以下函式庫不再內建,請安裝對應的 Gem 再使用。
- CMath (cmath gem)
- Scanf (scanf gem)
- Shell (shell gem)
- Synchronizer (sync gem)
- ThreadsWait (thwait gem)
- E2MM (e2mmap gem)
-
profile.rb
從標準函式庫移除了。 - 將以下的函式庫納入標準函式庫
- 同時發佈在 rubygems.org
- benchmark
- cgi
- delegate
- getoptlong
- net-pop
- net-smtp
- open3
- pstore
- singleton
- 只是納入了 ruby-core 但未發佈在 rubygems.org
- monitor
- observer
- timeout
- tracer
- uri
- yaml
- 同時發佈在 rubygems.org
-
對沒有區塊的
Proc.new
和proc
方法,用區塊呼叫會報一個警告訊息。 -
對沒有區塊的
lambda
的方法,用區塊呼叫則會拋一個異常。 -
更新 Unicode version and Emoji version 從 11.0.0 至 12.0.0。 [Feature #15321]
-
更新 Unicode version 至 12.1.0,支援方塊版的令和新年號(U+32FF)。 [Feature #15195]
-
Date.jisx0301
、Date#jisx0301
、Date.parse
現可以解析日本新年號 [Feature #15742] - 需使用支援 C99 的編譯器 [Misc #15347]
以上自 2.6.0 以來,計 4190 檔案變更,227498 行新增(+),99979 行刪減(-)!
耶誕快樂、佳節愉快,享受與 Ruby 2.7 一起寫程式的時光!
下載
-
https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.bz2
SIZE: 14703381 SHA1: b54f4633174dbc55db77d9fd6d0ef90cc35503af SHA256: 7aa247a19622a803bdd29fdb28108de9798abe841254fe8ea82c31d125c6ab26 SHA512: 8b8dd0ceba65bdde53b7c59e6a84bc6bf634c676bfeb2ff0b3604c362c663b465397f31ff6c936441b3daabb78fb7a619be5569480c95f113dd0453488761ce7
-
https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.gz
SIZE: 16799684 SHA1: 6f4e99b5556010cb27e236873cb8c09eb8317cd5 SHA256: 8c99aa93b5e2f1bc8437d1bbbefd27b13e7694025331f77245d0c068ef1f8cbe SHA512: 973fc29b7c19e96c5299817d00fbdd6176319468abfca61c12b5e177b0fb0d31174a5a5525985122a7a356091a709f41b332454094940362322d1f42b77c9927
-
https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.xz
SIZE: 11990900 SHA1: 943c767cec037529b8e2d3cc14fc880cad5bad8d SHA256: 27d350a52a02b53034ca0794efe518667d558f152656c2baaf08f3d0c8b02343 SHA512: dd5690c631bf3a2b76cdc06902bcd76a89713a045e136debab9b8a81ff8c433bbb254aa09e4014ca1cf85a69ff4bcb13de11da5e40c224e7268be43ef2194af7
-
https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.zip
SIZE: 20571744 SHA1: fbebdd3a2a641f9a81f7d8db5abd926acea27e80 SHA256: 8bf2050fa1fc76882f878fd526e4184dc54bd402e385efa80ef5fd3b810522e0 SHA512: 5060f2dd3bfd271ef255b17589d6d014260d7ec2d97b48112b717ee01c62fe125c3fe04f813e02d607cea3f0a2a812b14eb3a28d06c2551354dfeff5f4c3dd6b
Ruby 是
Ruby 最早由 Matz(松本行弘)於 1993 年開發,現在開發由開源社群所維護。Ruby 可以在多個平台上運行,廣受世人喜愛用於開發網路應用。