Posted by naruse on 25 Dec 2024
Ruby 3.4.0 が公開されました。Ruby 3.4では、ブロックパラメータ参照の it
の追加、
デフォルトパーサーのPrismへの変更、Socket ライブラリの Happy Eyeballs Version 2 (RFC 8305) 対応、YJITの改善、
Modular GCの導入など様々な改善が行われています。
it
の追加
ブロックパラメータに名前をつけずに参照する it
が追加されました。 [Feature #18980]
ary = ["foo", "bar", "baz"]
p ary.map { it.upcase } #=> ["FOO", "BAR", "BAZ"]
it
は _1
とほとんど同じように動作します。ブロック内で _1
のみを使用する意図がある場合に _1
を使うと、_2
や _3
などの他の番号付きパラメータが現れる可能性が示唆され、認知的負荷が高い問題がありました。そのため、it
は便利なエイリアスとして導入されました。一行ブロックなど、it
の意味が一目でわかる簡単なケースにご利用ください。
デフォルトのパーサをPrismに変更
デフォルトで使用するパーサーを parse.y から生成するパーサーから Prism へと変更しました。 [Feature #20564]
これは内部的な改善であり、ユーザーにはほとんど変化が見られないはずです。互換性の問題にお気づきの場合は、ご報告ください。
従来のパーサーを使用するにはコマンドライン引数 --parser=parse.y
を使用してください。
Socket ライブラリの Happy Eyeballs Version 2 (RFC 8305) 対応
Socket ライブラリの TCPSocket.new
(TCPSocket.open
) と Socket.tcp
が多数のプログラミング言語で、より良いネットワーク接続の方法として広く標準採用されている Happy Eyeballs Version 2 (RFC 8305) に対応しました。この改善により、Ruby は IPv6 と IPv4 が混在するような最新のインターネット環境においても、効率的で信頼性の高いネットワーク接続が可能となりました。
Ruby 3.3 までは上記の2つのメソッドは名前解決と接続試行をシリアルに実行していました。Happy Eyeballs Version 2 のアルゴリズムでは以下のように実行します。
- IPv6とIPv4の名前解決を同時実行する。
- 解決されたIPアドレスへの接続を、IPv6を優先して、250ミリ秒間隔で並行して試みる。
- 最初に成功した接続を返し、他の接続はキャンセルする。
このアルゴリズムによって、特定のプロトコルや IP アドレスが遅延したり利用できない場合でも、接続遅延を最小限に抑えることが可能となります。
この機能は標準で有効になるため、追加の設定は必要ありません。Ruby 全体で無効にしたい場合は環境変数として RUBY_TCP_NO_FAST_FALLBACK=1
を設定するか、Socket.tcp_fast_fallback=false
を Ruby プログラムの中で呼び出してください。またはメソッド単位で無効化する場合、TCPSocket.new
(TCPSocket.open
) と Socket.tcp
のキーワード引数として fast_fallback: false
を利用してください。
YJIT
TL;DR
- x86-64 と arm64 の両方のプラットフォームにおいて、ほとんどのベンチマークのパフォーマンスが向上しました。
- メタデータの圧縮と統一的なメモリ使用量制限によりメモリ使用量を削減しました。
- 様々な不具合修正: YJIT はより堅牢になり、より多くの環境でテストされました。
新機能
- コマンドラインオプション
--yjit-mem-size
による統一的なメモリ制限が指定可能になりました(デフォルトは 128MiB)。 このオプションはすべての YJIT のメモリ使用量を監視し、従来の--yjit-exec-mem-size
オプションよりも直感的に使用できます。--yjit-log
オプションを用いて、コンパイルログを監視できるようになりました。
- Ruby API
RubyVM::YJIT.log
を用いてコンパイルログの末尾を取得することができるようになりました。
- YJIT の統計情報
RubyVM::YJIT.runtime_stats
からインバリデーション、インライン化、メタデータエンコーディングに関する追加の統計情報をいつでも取得できるようになりました。
新しい最適化
- コンテキストの圧縮化により YJIT のメタデータ保管に必要なメモリを削減しました。
- ローカル変数やRubyのメソッドの引数のためにレジスタを割り当てるようになりました。
- YJIT が有効な場合に Ruby で実装されたコアクラスを使うようになりました。
- Ruby で書き直された
Array#each
,Array#select
,Array#map
はより良いパフォーマンスを提供します。 [Feature #20182].
- Ruby で書き直された
- 以下のような小さいメソッドをインライン化できるようになりました:
- 空メソッド
- 定数を返すメソッド
self
を返すメソッド- 引数を直接返すメソッド
- 組み込みメソッドに特化したコード生成の対象を広げました
String#getbyte
,String#setbyte
など、String のメソッドの最適化を行いました。- 低レベルの bit/byte 操作を高速化するためにビット演算を最適化しました
- マルチ Ractor モードにおける定数共有をサポートしました。
- その他、様々な段階的な最適化を行いました。
Modular GC
-
Modular GC 機能により Ruby 標準とは異なる ガベージ・コレクタ (GC) の実装を動的にロードすることができるようになりました。この機能を使うには Ruby をビルドする時に
--with-modular-gc
を指定してください。GC ライブラリは環境変数RUBY_GC_LIBRARY
を用いて Ruby のランタイムにロードすることができます。[Feature #20351] -
Ruby 組み込みのガベージ・コレクタは
gc/default/default.c
ファイルに分割され、 Ruby ランタイムとのやりとりはgc/gc_impl.h
に定義される API を用いて行われます。組み込みのガベージコレクタはmake modular-gc MODULAR_GC=default
というコマンドを用いてライブラリとしてもビルドすることができ、環境変数としてRUBY_GC_LIBRARY=default
を定義することで有効にすることができます。 [Feature #20470] -
MMTk をベースとした実験的な GC ライブラリが提供されました。このライブラリは
make modular-gc MODULAR_GC=mmtk
コマンドによってビルドし、環境変数RUBY_GC_LIBRARY=mmtk
によって有効化します。この機能を使うにはビルドを行うマシンに Rust のビルドツールを必要とします。 [Feature #20860]
言語機能の変更
-
マジックコメント
frozen_string_literal
のないファイル中の文字列リテラルは、freeze されているかのように振る舞うようになり、破壊的な変更時に警告を表示するようになりました。これらの警告はコマンドラインオプション-W:deprecated
か Ruby プログラムでWarning[:deprecated] = true
を指定すると表示されます。 これら無効にするにはコマンドラインオプション--disable-frozen-string-literal
を追加して Ruby を実行してください。 [Feature #20205] -
メソッド呼び出し時の
nil
展開キーワードがサポートされました。**nil
は**{}
と同様に扱われ、キーワードは渡せません。 また、あらゆる変換のためのメソッドも呼ばれません。[Bug #20064] -
インデックスにブロックを渡せなくなりました。[Bug #19918]
-
インデックスにキーワード引数を渡せなくなりました。[Bug #20218]
-
トップレベルに
::Ruby
を予約しました。Warning[:deprecated]
が有効な場合、既に定義済みの場合は警告されます。[Feature #20884]
コアクラスのアップデート
注: 複数のアップデートの中から注目すべきアップデートのみを掲載しています。
-
Exception
Exception#set_backtrace
はThread::Backtrace::Location
の配列を受け取れる様になりました。.Kernel#raise
,Thread#raise
やFiber#raise
も同じ配列を受け取れます。[Feature #13557]
-
GC
-
GC.config
がガベージ・コレクタの設定変更を可能とするために追加されました。[Feature #20443] -
GC の設定用のパラメータとして
rgengc_allow_full_mark
が追加されました。このパラメータをfalse
とすると、GC は young オブジェクトのみを GC 用にマークします。デフォルト値はtrue
です。 [Feature #20443]
-
-
Ractor
-
Ractor の中で
require
が可能となりました。このrequire
の処理はメインの Ractor で行われます。 また、メインの Ractor にはrequire
処理のためにRactor._require(feature)
が追加されました。 [Feature #20627] -
Ractor.main?
が追加されました。[Feature #20627] -
現在実行中の Ractor の Ractor ローカルストレージにアクセスするためのメソッドとして
Ractor.[]
andRactor.[]=
が追加されました。 [Feature #20715] -
スレッドセーフに Ractor ローカル変数を初期化するためのメソッド
Ractor.store_if_absent(key){ init }
が追加されました。 [Feature #20875]
-
-
Range
Range#size
は範囲オブジェクトが反復可能ではない場合はTypeError
例外を出すようになりました。[Misc #18984]
標準ライブラリのアップデート
注: 複数のアップデートの中から注目すべき標準ライブラリのアップデートのみを掲載しています。
- RubyGems
gem push
コマンドに--attestation
オプションが追加されました。このオプションをつけると sigstore に gem の署名情報が保存されます。
- Bundler
- ロックファイルの新規作成時に gem の checksum を保存する
lockfile_checksums
オプションがbundle config
に設定可能になりました。 - 既存のロックファイルに使用している gem の checksum を付与するためのコマンドとして
bundle lock --add-checksums
が追加されました。
- ロックファイルの新規作成時に gem の checksum を保存する
-
JSON
JSON.parse
が Ruby 3.3 シリーズに添付されている json-2.7.x と比較して 1.5 倍程度高速になりました。
-
Tempfile
Tempfile.create
にanonymous: true
キーワードが追加されました。Tempfile.create(anonymous: true)
は作成した一時ファイルを即座に削除します。この機能を用いることで、アプリケーションは独自にファイル削除を行う必要がなくなります。 [Feature #20497]
-
win32/sspi.rb
- Windows で SSPI 機能を提供するライブラリは Ruby のリポジトリから ruby/net-http-sspi に移動しました。 [Feature #20775]
互換性に関する変更
注: 不具合修正を除きます。
- エラーメッセージとして表示するバックトレースを変更しました。
- 開始の引用符は backtick の代わりにシングルクォートを用いるようになりました。[Feature #16495]
- クラス名が変更しないような場合、メソッド名の前にクラス名を表示するようになりました。[Feature #19117]
Kernel#caller
,Thread::Backtrace::Location
などのメソッドはそれらに応じて変更されました。
Old: test.rb:1:in `foo': undefined method `time' for an instance of Integer from test.rb:2:in `<main>' New: test.rb:1:in 'Object#foo': undefined method 'time' for an instance of Integer from test.rb:2:in '<main>'
-
Hash#inspect
の表示が変わりました。[[Bug #20433]]- Symbol キーはコロンを用いたモダンな表示になりました:
"{user: 1}"
- 他のキーは従来の
'{"user"=>1}'
とは異なり、=>
の前後にスペースを含む表示になりました:'{"user" => 1}'
。
- Symbol キーはコロンを用いたモダンな表示になりました:
-
Kernel#Float()
は 10 進表記の小数部がなくても受け付けるようになりました。 [Feature #20705]Float("1.") #=> 1.0 (previously, an ArgumentError was raised) Float("1.E-1") #=> 0.1 (previously, an ArgumentError was raised)
-
String#to_f
は 10 進表記の小数部がなくても受け付けるようになりました。指数を指定すると従来とは結果が変わることに注意してください。 [Feature #20705]"1.".to_f #=> 1.0 "1.E-1".to_f #=> 0.1 (previously, 1.0 was returned)
Refinement#refined_class
は削除されました。[Feature #19714]
標準ライブラリの互換性の変更
-
DidYouMean
DidYouMean::SPELL_CHECKERS[]=
とDidYouMean::SPELL_CHECKERS.merge!
は削除されました。
-
Net::HTTP
- 2012 年から非推奨とされている以下の定数が削除されました。
Net::HTTP::ProxyMod
Net::NetPrivate::HTTPRequest
Net::HTTPInformationCode
Net::HTTPSuccessCode
Net::HTTPRedirectionCode
Net::HTTPRetriableCode
Net::HTTPClientErrorCode
Net::HTTPFatalErrorCode
Net::HTTPServerErrorCode
Net::HTTPResponseReceiver
Net::HTTPResponceReceiver
- 2012 年から非推奨とされている以下の定数が削除されました。
-
Timeout
Timeout.timeout
が負の値を受け付けなくなりました。[Bug #20795]
-
URI
- デフォルトのパーサーが RFC 2396 準拠のものから RFC 3986 準拠のものに変わりました。 [Bug #19266]
C API のアップデート
rb_newobj
とrb_newobj_of
(と対応するマクロのRB_NEWOBJ
,RB_NEWOBJ_OF
,NEWOBJ
,NEWOBJ_OF
) は削除されました。 [Feature #20265]- 非推奨とされていた
rb_gc_force_recycle
は削除されました。 [Feature #18290]
その他の変更点
-
渡されたブロックを使用しないメソッドにブロックを渡すと、verboseモード(
-w
) で警告が表示されるようになりました。[Feature #15554] -
String.freeze
やInteger#+
のような JIT とインタプリタによって特別に最適化されたメソッドを再定義すると、performance 警告(-W:performance
またはWarning[:performance] = true
で有効化)が表示されるようになりました。 [Feature #20429]
より詳細な情報は NEWS か commit logs を参照してください。
これらの変更により、Ruby 3.3.0から 4942 ファイルが変更され、 202244 行が追加され、 255528 行が削除されました!deletions(-)
メリークリスマス、Ruby 3.4 とともによいお年をお迎えください!
Download
-
https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.tar.gz
SIZE: 23153022 SHA1: 8ccb561848a7c460ae08e1a120a47c4a88a79335 SHA256: 068c8523442174bd3400e786f4a6952352c82b1b9f6210fd17fb4823086d3379 SHA512: bc70ecba27d1cdea00879f03487cad137a7d9ab2ad376cfb7a65780ad14da637fa3944eeeede2c04ab31eeafb970c64ccfeeb854c99c1093937ecc1165731562
-
https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.tar.xz
SIZE: 17215572 SHA1: eb25447cc404e8d2e177c62550d0224ebd410e68 SHA256: 0081930db22121eb997207f56c0e22720d4f5d21264b5907693f516c32f233ca SHA512: 776a2cf3e9ccc77c27500240f168aa3e996b0c7c1ee1ef5a7afc291a06c118444016fde38b5b139c0b800496b8eb1b5456562d833f0edc0658917164763b1af7
-
https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.zip
SIZE: 28310193 SHA1: 26254ca5d3decc28a4e5faec255995265e5270b5 SHA256: c120228038af04554f6363e716b0a32cbf53cf63c6adf9f2c22a24f43dc8b555 SHA512: 4d535ed10db76a6aa74f8a025df319deb28483a7a781c24045906ee7663f1cff9d9f9e71dbc993c9e050113a34b37c7fa2143c355a0a6e1e1029bf2c92213ecc
What is Ruby
Rubyはまつもとゆきひろ (Matz) によって1993年に開発が始められ、今もオープンソースソフトウェアとして開発が続けられています。Rubyは様々なプラットフォームで動き、世界中で、特にWebアプリケーション開発のために使われています。