Skip to content

Commit 8339201

Browse files
timfanda35hsbt
authored andcommitted
Translate Ruby 3.2.0 preview3 released news post (zh_tw)
1 parent 33e255c commit 8339201

File tree

1 file changed

+378
-0
lines changed

1 file changed

+378
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
---
2+
layout: news_post
3+
title: "Ruby 3.2.0 Preview 3 Released"
4+
author: "naruse"
5+
translator: "Bear Su"
6+
date: 2022-11-11 00:00:00 +0000
7+
lang: zh_tw
8+
---
9+
10+
{% assign release = site.data.releases | where: "version", "3.2.0-preview3" | first %}
11+
12+
我們很高興宣佈 Ruby {{ release.version }} 發佈了. Ruby 3.2 新增許多新功能及效能提升.
13+
14+
15+
## 基於 WASI 的 WebAssembly 支援
16+
17+
這是首次基於 WASI 支援 WebAssembly。使得 CRuby binary 可用於網頁瀏覽器、Serverless Edge 環境、與其他 WebAssembly/WASI 嵌入式環境. 目前已通過 basic 與 bootstrap 測試,但不包括 Thread API。
18+
19+
![](https://i.imgur.com/opCgKy2.png)
20+
21+
### 背景
22+
23+
[WebAssembly (Wasm)](https://webassembly.org/) 最初是為了在網頁瀏覽器中安全快速地執行程式。但其目標 - 在不同的環境上安全又有效率的執行程式,不僅是 web 應用程式,也是其他一般應用程式的目標。
24+
25+
[WASI (The WebAssembly System Interface)](https://wasi.dev/) 被設計用於此使用場景。 儘管應用程式需要與作業系統溝通,但 WebAssembly 卻是運行在沒有系統介面的虛擬機中。WASI 將其標準化了。
26+
27+
Ruby 中的 WebAssembly/WASI 支援透過這些專案,允許 Ruby 開發者可以開發在相容此功能的平台上執行的應用程式。
28+
29+
### 使用場景
30+
31+
此支援功能使得開發者可以在 WebAssembly 環境上使用 CRuby。 其中一個範例就是 [TryRuby playground](https://try.ruby-lang.org/playground/) 的 CRuby 支援。現在您可以在您的網頁瀏覽器上嘗試原生的 CRuby。
32+
33+
### 技術特點
34+
35+
因為目前 WASI 和 WebAssembly 不斷地再改進與安全性理由,仍缺少一些功能來實現 Fiber、異常、和 GC。所以 CRuby 透過使用 Asyncify,一個在使用者空間的 binary 轉換技術,來彌補中間的差距。
36+
37+
並且,我們建置了 [a VFS on top of WASI](https://github.com/kateinoigakukun/wasi-vfs/wiki/Getting-Started-with-CRuby),讓我們可以很容易地將 Ruby 應用程式打包成單一 .wasm 檔案。簡化了 Ruby 應用程式的分發過程。
38+
39+
40+
### 相關連結
41+
42+
* [Add WASI based WebAssembly support #5407](https://github.com/ruby/ruby/pull/5407)
43+
* [An Update on WebAssembly/WASI Support in Ruby](https://itnext.io/final-report-webassembly-wasi-support-in-ruby-4aface7d90c9)
44+
45+
## Regexp 增強 ReDoS 防禦
46+
47+
眾所皆知 Regexp matching 所花的時間可能會非預期的久。如果您的程式使用效率可能較低的 Regexp 來比對不可信的輸入內容,攻擊者可能可以藉此來發動服務阻斷攻擊。(稱為 Regular expression DoS, or ReDoS)。
48+
49+
我們進行了兩項改進,可以顯著降低 ReDos 攻擊的影響。
50+
51+
### 改善 Regexp 比對演算法
52+
53+
從 Ruby 3.2 開始,透過使用 memoization 技術,Regexp 的比對演算法得到了很大的改進。
54+
55+
```
56+
# 這個比對在 Ruby 3.1 需要花費 10 秒。 而在 Ruby 3.2 只需要花費 0.003 秒。
57+
58+
/^a*b?a*$/ =~ "a" * 50000 + "x"
59+
```
60+
61+
改進後的演算法使得大部分的 Regexp (我們實驗中的 90%) 可以在線性時間內完成。
62+
63+
(給預覽使用者:這個改善可能會花費與輸入長度成比例的記憶體。我們預期這不會有實際問題,因為這種記憶體分配通常都會延遲,而正常的 Regexp 最多可花費輸入長度 10 倍的記憶體。如果您在現實場景中使用 Regexp 進行比對時遇到記憶題不足的問題,請向我們回報。)
64+
65+
最初提案:<https://bugs.ruby-lang.org/issues/19104>
66+
67+
### Regexp 逾時設定
68+
69+
上述的改善無法套用在某些 Regexp,像是包含進階功能 (例如:back-references 或是 look-around),或有大量固定重複次數。作為備案,我們在 Regexp 比對中導入了逾時設定。
70+
71+
```ruby
72+
Regexp.timeout = 1.0
73+
74+
/^a*b?a*()\1$/ =~ "a" * 50000 + "x"
75+
#=> 1 秒後拋出 Regexp::TimeoutError
76+
```
77+
78+
注意 `Regexp.timeout` 是全域設定。如果您想要為一些特定的 Regexps 使用不同的逾時設定,您可以在呼叫 `Regexp.new` 時使用 `timeout` keyword。
79+
80+
```ruby
81+
Regexp.timeout = 1.0
82+
83+
# This regexp has no timeout
84+
long_time_re = Regexp.new('^a*b?a*()\1$', timeout: Float::INFINITY)
85+
86+
long_time_re =~ "a" * 50000 + "x" # 不會被中斷
87+
```
88+
89+
最初提案:<https://bugs.ruby-lang.org/issues/17837>
90+
91+
## 其他值得注意的新功能
92+
93+
### 不再綑綁第三方原始碼
94+
95+
* 我們不再綑綁第三方原始碼像是 `libyaml`, `libffi`
96+
97+
* psych 中的 libyaml 原始碼已經被移除。您可能需要在 Ubuntu/Debian 平台上安裝 `libyaml-dev`。 每個平台上的套件名稱有所不同。
98+
99+
* 綑綁的 libffi 原始碼也從 `fiddle` 中被移除
100+
101+
### 語言功能
102+
103+
* 除了作為方法參數,匿名不定長度參數現在也可以傳遞為其他方法的參數。
104+
[[Feature #18351]]
105+
106+
```ruby
107+
def foo(*)
108+
bar(*)
109+
end
110+
def baz(**)
111+
quux(**)
112+
end
113+
```
114+
115+
* 只接收單一參數的 proc 將不會自動解開封裝。 [[Bug #18633]]
116+
117+
```ruby
118+
proc{|a, **k| a}.call([1, 2])
119+
# Ruby 3.1 與之前的版本
120+
# => 1
121+
# Ruby 3.2 與之後的版本
122+
# => [1, 2]
123+
```
124+
125+
* 常數賦值評估順序將與單一屬性賦值評估順序保持一致。參考以下程式碼:
126+
127+
```ruby
128+
foo::BAR = baz
129+
```
130+
131+
`foo` 現在會在 `baz` 之前被呼叫。同樣地,在有多個賦值給常數的情況,會使用從左至右的順序評估。參考以下程式碼:
132+
133+
```ruby
134+
foo1::BAR1, foo2::BAR2 = baz1, baz2
135+
```
136+
137+
現在使用下面的評估顺序:
138+
139+
1. `foo1`
140+
2. `foo2`
141+
3. `baz1`
142+
4. `baz2`
143+
144+
[[Bug #15928]]
145+
146+
* Find pattern 不再是實驗性功能。
147+
[[Feature #18585]]
148+
149+
* 使用不定長度參數 (例如 `*args`) 的方法,如果同時希望可以作為 keyword 參數傳遞給 `foo(*args)`。必須標記為 `ruby2_keywords` (若還未標記)。
150+
換句話說,希望作為接收 keyword 參數的其他方法都毫無例外地必須標記為 `ruby2_keywords`。若某個函式庫需要使用 Ruby 3+,這會是一個較為容易的過渡升級方法。
151+
在此之前,當接受方法取得 `*args`時會保留 `ruby2_keywords` 標記,但這是一個錯誤且行為不一致。
152+
對於找到可能缺少 `ruby2_keywords` 標記的好方法是執行測試,在測試失敗的地方,找到最後一個接收 keyword 參數的方法,在哪裡使用 `puts nil, caller, nil`,並檢查每一個在呼叫鏈上的方法/區塊,是否都被正確地標記為 `ruby2_keywords`。[[Bug #18625]] [[Bug #16466]]
153+
154+
```ruby
155+
def target(**kw)
156+
end
157+
158+
# 意外地 Ruby 2.7-3.1 在沒有 ruby2_keywords 的情況下可以成功
159+
# 執行,但在 3.2+ 卻是必需的。若需移除 ruby2_keywords,
160+
# #foo 和 #bar 需要將參數改成 (*args, **kwargs) 或 (...)
161+
ruby2_keywords def bar(*args)
162+
target(*args)
163+
end
164+
165+
ruby2_keywords def foo(*args)
166+
bar(*args)
167+
end
168+
169+
foo(k: 1)
170+
```
171+
172+
## 效能改善
173+
174+
### YJIT
175+
176+
* 支援 arm64 / aarch64 架構的 UNIX 平台。
177+
* 建置 YJIT 時需要 Rust 1.58.1+ 。 [[Feature #18481]]
178+
179+
## Other notable changes since 3.1
180+
181+
* Hash
182+
* 當 hash 為空時, Hash#shift 現在總是回傳 nil,取代以往回傳預設值或呼叫預設的 proc。 [[Bug #16908]]
183+
184+
* MatchData
185+
* 已新增 MatchData#byteoffset。 [[Feature #13110]]
186+
187+
* Module
188+
* 已新增 Module.used_refinements。 [[Feature #14332]]
189+
* 已新增 Module#refinements。 [[Feature #12737]]
190+
* 已新增 Module#const_added。 [[Feature #17881]]
191+
192+
* Proc
193+
* Proc#dup 回傳子類別的實體。 [[Bug #17545]]
194+
* Proc#parameters 現在接受 lambda keyword。 [[Feature #15357]]
195+
196+
* Refinement
197+
* 已新增 Refinement#refined_class。 [[Feature #12737]]
198+
199+
* RubyVM::AbstractSyntaxTree
200+
* `parse`, `parse_file``of` 新增 `error_tolerant` 選項。 [[Feature #19013]]
201+
202+
* Set
203+
* Set 現在可以直接使用,不再需要先 `require "set"`。 [[Feature #16989]]
204+
目前是透過 `Set` 常數或呼叫 `Enumerable#to_set` 來自動載入。
205+
206+
207+
* String
208+
* 已新增 String#byteindex 和 String#byterindex。 [[Feature #13110]]
209+
* 更新 UnicodeVersion 14.0.0Emoji Version 14.0。 [[Feature #18037]] (也適用於 Regexp)
210+
* 已新增 String#bytesplice。 [[Feature #18598]]
211+
212+
* Struct
213+
* `Struct.new` 不需要傳入 `keyword_init: true` 也可以透過 keyword 參數初始化。 [[Feature #16806]]
214+
215+
## 相容性問題
216+
217+
注意:不包含功能問題的修正。
218+
219+
### 被移除的常數
220+
221+
下列廢棄的常數已被移除。
222+
223+
* `Fixnum``Bignum` [[Feature #12005]]
224+
* `Random::DEFAULT` [[Feature #17351]]
225+
* `Struct::Group`
226+
* `Struct::Passwd`
227+
228+
### 被移除的方法
229+
230+
下列廢棄的方法已被移除。
231+
232+
* `Dir.exists?` [[Feature #17391]]
233+
* `File.exists?` [[Feature #17391]]
234+
* `Kernel#=~` [[Feature #15231]]
235+
* `Kernel#taint`, `Kernel#untaint`, `Kernel#tainted?`
236+
[[Feature #16131]]
237+
* `Kernel#trust`, `Kernel#untrust`, `Kernel#untrusted?`
238+
[[Feature #16131]]
239+
240+
## Stdlib 相容性問題
241+
242+
* `Psych` 不再綑綁 libyaml 原始碼.
243+
使用者需要透過套件管理系統自行安裝 libyaml 函式庫。 [[Feature #18571]]
244+
245+
## C API 更新
246+
247+
### Updated C APIs
248+
249+
以下是更新的 APIs
250+
251+
* PRNG 更新
252+
`rb_random_interface_t` 更新版本。
253+
使用此舊版介面建置的擴展函式庫還需要定義 `init_int32` 函式。
254+
255+
### 被移除的 C APIs
256+
257+
下列廢棄的 APIs 已被移除。
258+
259+
* `rb_cData` 變數。
260+
* "taintedness""trustedness" 函式. [[Feature #16131]]
261+
262+
### 標準函式庫更新
263+
264+
* SyntaxSuggest
265+
266+
* 被稱為 `dead_end``syntax_suggest` 以整合進 Ruby
267+
[[Feature #18159]]
268+
269+
* ErrorHighlight
270+
* 現在指向 TypeErrorArgumentError 的參數
271+
272+
```
273+
test.rb:2:in `+': nil can't be coerced into Integer (TypeError)
274+
275+
sum = ary[0] + ary[1]
276+
^^^^^^
277+
```
278+
279+
* 更新了以下預設 gems。
280+
* RubyGems 3.4.0.dev
281+
* bigdecimal 3.1.2
282+
* bundler 2.4.0.dev
283+
* cgi 0.3.2
284+
* date 3.2.3
285+
* error_highlight 0.4.0
286+
* etc 1.4.0
287+
* io-console 0.5.11
288+
* io-nonblock 0.1.1
289+
* io-wait 0.3.0.pre
290+
* ipaddr 1.2.4
291+
* json 2.6.2
292+
* logger 1.5.1
293+
* net-http 0.2.2
294+
* net-protocol 0.1.3
295+
* ostruct 0.5.5
296+
* psych 5.0.0.dev
297+
* reline 0.3.1
298+
* securerandom 0.2.0
299+
* set 1.0.3
300+
* stringio 3.0.3
301+
* syntax_suggest 0.0.1
302+
* timeout 0.3.0
303+
* 更新了以下 bundled gems。
304+
* minitest 5.16.3
305+
* net-imap 0.2.3
306+
* rbs 2.6.0
307+
* typeprof 0.21.3
308+
* debug 1.6.2
309+
* 以下預設 gems 現在成為了 bundled gems。
310+
311+
參見 [NEWS](https://github.com/ruby/ruby/blob/{{ release.tag }}/NEWS.md)
312+
和 [commit logs](https://github.com/ruby/ruby/compare/v3_1_0...{{ release.tag }}) 來了解更多。
313+
314+
自 Ruby 3.1.0 以來,計 [{{ release.stats.files_changed }} 檔案變更, {{ release.stats.insertions }} 行新增 (+), {{ release.stats.deletions }} 行刪減 (-)](https://github.com/ruby/ruby/compare/v3_1_0...{{ release.tag }}#file_bucket)!
315+
316+
## 下載
317+
318+
* <{{ release.url.gz }}>
319+
320+
SIZE: {{ release.size.gz }}
321+
SHA1: {{ release.sha1.gz }}
322+
SHA256: {{ release.sha256.gz }}
323+
SHA512: {{ release.sha512.gz }}
324+
325+
* <{{ release.url.xz }}>
326+
327+
SIZE: {{ release.size.xz }}
328+
SHA1: {{ release.sha1.xz }}
329+
SHA256: {{ release.sha256.xz }}
330+
SHA512: {{ release.sha512.xz }}
331+
332+
* <{{ release.url.zip }}>
333+
334+
SIZE: {{ release.size.zip }}
335+
SHA1: {{ release.sha1.zip }}
336+
SHA256: {{ release.sha256.zip }}
337+
SHA512: {{ release.sha512.zip }}
338+
339+
## Ruby 是什麼
340+
341+
Ruby 最初由 Matz(Yukihiro Matsumoto)於 1993 年開發的開源軟體。可以在許多平台上執行。使用者來自世界各地,特別活躍於網路開發領域。
342+
343+
344+
345+
[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
346+
[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
347+
[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
348+
[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
349+
[Feature #14332]: https://bugs.ruby-lang.org/issues/14332
350+
[Feature #15231]: https://bugs.ruby-lang.org/issues/15231
351+
[Feature #15357]: https://bugs.ruby-lang.org/issues/15357
352+
[Bug #15928]: https://bugs.ruby-lang.org/issues/15928
353+
[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
354+
[Bug #16466]: https://bugs.ruby-lang.org/issues/16466
355+
[Feature #16806]: https://bugs.ruby-lang.org/issues/16806
356+
[Bug #16889]: https://bugs.ruby-lang.org/issues/16889
357+
[Bug #16908]: https://bugs.ruby-lang.org/issues/16908
358+
[Feature #16989]: https://bugs.ruby-lang.org/issues/16989
359+
[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
360+
[Feature #17391]: https://bugs.ruby-lang.org/issues/17391
361+
[Bug #17545]: https://bugs.ruby-lang.org/issues/17545
362+
[Feature #17881]: https://bugs.ruby-lang.org/issues/17881
363+
[Feature #18037]: https://bugs.ruby-lang.org/issues/18037
364+
[Feature #18159]: https://bugs.ruby-lang.org/issues/18159
365+
[Feature #18351]: https://bugs.ruby-lang.org/issues/18351
366+
[Bug #18487]: https://bugs.ruby-lang.org/issues/18487
367+
[Feature #18571]: https://bugs.ruby-lang.org/issues/18571
368+
[Feature #18585]: https://bugs.ruby-lang.org/issues/18585
369+
[Feature #18598]: https://bugs.ruby-lang.org/issues/18598
370+
[Bug #18625]: https://bugs.ruby-lang.org/issues/18625
371+
[Bug #18633]: https://bugs.ruby-lang.org/issues/18633
372+
[Feature #18685]: https://bugs.ruby-lang.org/issues/18685
373+
[Bug #18782]: https://bugs.ruby-lang.org/issues/18782
374+
[Feature #18788]: https://bugs.ruby-lang.org/issues/18788
375+
[Feature #18809]: https://bugs.ruby-lang.org/issues/18809
376+
[Feature #18481]: https://bugs.ruby-lang.org/issues/18481
377+
[Bug #19100]: https://bugs.ruby-lang.org/issues/19100
378+
[Feature #19013]: https://bugs.ruby-lang.org/issues/19013

0 commit comments

Comments
 (0)