Noriyo Akita's Today I Learned

# Ruby 3.4 リリースパーティー presented by STORES / アンドパッド

Table of Contents

Ruby 3.4 リリースパーティー presented by STORES / アンドパッド

https://andpad.connpass.com/event/336742/

it が目玉機能w

この位置で it が使える

"foo".then do
p "bar".then { it.upcase }
p it # ここ
end
"BAR"
"foo"
=> "foo"

ナンパラだと使えない

"foo".then do
p "bar".then { _1.upcase }
p _1
end
<internal:kernel>:168:in 'Kernel#loop': (irb):11: syntax error found (SyntaxError)
9 | "foo".then do
10 | p "bar".then { _1.upcase }
> 11 | p _1
| ^~ numbered parameter is already used in inner block
12 | end

frozon_string_literal がデフォルトの方向になる

なくなるわけではない。もっと後のバージョンアップでデフォルトになる

明示的に書く人は少ないのか? linter で怒られるんじゃないかなあ?

キーワード引数の **nil を渡せるようになった

空ハッシュを渡したのと同じ

def hello(name: "default")
puts "Hello, #{name}"
end
h = { name: "noriyo" }
hello(**h)
Hello, noriyo
h = nil
hello(**h)
Hello, default

Array#fetch_values が追加された

> ["foo", "bar", "baz"].fetch_values(1, 2)
=> ["bar", "baz"]
# 境界外のアクセスには IndexError
["foo", "bar", "baz"].fetch_values(1, 4)
<internal:array>:211:in 'Array#fetch': index 4 outside of array bounds: -3...3 (IndexError)
from <internal:array>:211:in 'block in Array#fetch_values'
from <internal:array>:211:in 'Array#map!'
from <internal:array>:211:in 'Array#fetch_values'
from (irb):10:in '<main>'
from <internal:kernel>:168:in 'Kernel#loop'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/irb-1.14.3/exe/irb:9:in '<top (required)>'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/bin/irb:25:in 'Kernel#load'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/bin/irb:25:in '<main>'
# block がある場合はそれを呼ぶ
["foo", "bar", "baz"].fetch_values(1, 4) { 42 }
=> ["bar", 42]
# values_at は境界外アクセスには nilを返す
> ["foo", "bar", "baz"].values_at(1, 4)
=> ["bar", nil]

Hash 生成時に必要な容量を指定できるようになった

capacity: で指定できるようになった

Terminal window
time ruby -e 'n = 10_000_000; h = Hash.new; n.times{ h[it] = it }'
ruby -e 'n = 10_000_000; h = Hash.new; n.times{ h[it] = it }' 2.63s user 0.29s system 85% cpu 3.421 total
time ruby -e 'n = 10_000_000; h = Hash.new(capacity: n); n.times{ h[it] = it }'
ruby -e 'n = 10_000_000; h = Hash.new(capacity: n); n.times{ h[it] = it }' 1.90s user 0.16s system 82% cpu 2.485 total

整数の整数乗が Float::INIFINITY を返さないようになった

# Before
> 2**136279841 - 1
(irb):2: warning: in a**b, b may be too big
=> Infinity
# after
# 時間がかかるが素直に計算している
> 2**136279841 - 1
=> 88169432750383326555393910037811735897120735450906604106715637641242263069475684144172599034772328310883750973995977687416411861067989576855>
# 結果はデカすぎて見切れている

each できない Range に対して Range#size が例外を投げるようになった

# before
(0.1..1).size
=> 1 # 今まで1を返していたのがびっくり
(...0).size
=> Infinity
# after
(0.1..1).size
(irb):1:in 'Range#size': can't iterate from Float (TypeError)
from (irb):1:in '<main>'
from <internal:kernel>:168:in 'Kernel#loop'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/irb-1.14.3/exe/irb:9:in '<top (required)>'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/bin/irb:25:in 'Kernel#load'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/bin/irb:25:in '<main>'
(...0).size
(irb):2:in 'Range#size': can't iterate from NilClass (TypeError)
from (irb):2:in '<main>'
from <internal:kernel>:168:in 'Kernel#loop'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/irb-1.14.3/exe/irb:9:in '<top (required)>'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/bin/irb:25:in 'Kernel#load'
from /Users/noriyo_tcp/.rbenv/versions/3.4.1/bin/irb:25:in '<main>'

Time の Range に対して Range#step が使える

これは捗りそう

> pp (Time.new(2000, 1, 1)...).step(86400).take(3)
[2000-01-01 00:00:00 +0900, 2000-01-02 00:00:00 +0900, 2000-01-03 00:00:00 +0900]

Hash#inspect の結果が変わった

# before
h = { user: 1 }
=> {:user=>1} # この時点でファットアロー
p h
=> {:user=>1}
# after
h = { user: 1 }
=> {user: 1}
p h
{user: 1}

テストで => を使った文字列が返ってくるのを期待するとこけるかも
そもそも inspect の結果をテストの期待値に使うべきではないのか。 request の結果なんかに使ったりするかなあ?どうなんだろ

小数から文字列への変換時に、小数部なし文字列を解釈するようになった

# before
Float("1.")
<internal:kernel>:214:in `Float': invalid value for Float(): "1." (ArgumentError)
from (irb):7:in `<main>'
from <internal:kernel>:187:in `loop'
from /Users/noriyo_tcp/.rbenv/versions/3.3.4/lib/ruby/gems/3.3.0/gems/irb-1.13.1/exe/irb:9:in `<top (required)>'
from /Users/noriyo_tcp/.rbenv/versions/3.3.4/bin/irb:25:in `load'
from /Users/noriyo_tcp/.rbenv/versions/3.3.4/bin/irb:25:in `<main>'
Float("1.E-1")
<internal:kernel>:214:in `Float': invalid value for Float(): "1.E-1" (ArgumentError)
from (irb):8:in `<main>'
from <internal:kernel>:187:in `loop'
from /Users/noriyo_tcp/.rbenv/versions/3.3.4/lib/ruby/gems/3.3.0/gems/irb-1.13.1/exe/irb:9:in `<top (required)>'
from /Users/noriyo_tcp/.rbenv/versions/3.3.4/bin/irb:25:in `load'
from /Users/noriyo_tcp/.rbenv/versions/3.3.4/bin/irb:25:in `<main>'
# after
Float("1.")
=> 1.0
Float("1.E-1")
=> 0.1

Happy Eyebools v2

IPv4, IPv6 に同時並行で接続しにいって、先に応答があったほうで接続を開始する

katakata_irb -> repl_type_completorbundled gem になった

名前が変わったの知らなかった

JSON の性能が向上

これは嬉しい!

Ruby のリリースについて

CI が通っていればリリース可能とみなす。実務で問題が出るかはまた別
チケットはたくさんあるけどそれを気にしていたらリリースできない(それはそう)

参考記事:
プロと読み解くRuby 3.4 NEWS - STORES Product Blog

My avatar

Thanks for reading my blog post! Feel free to check out my other posts or contact me via the social links in the footer.


More Posts