Ruby 4.0.0 リリース
Posted by naruse on 25 Dec 2025
Ruby 4.0.0 が公開されました。 Ruby 4.0 には “Ruby Box”、”ZJIT” ほか多数の改善が含まれています。
Ruby Box
Ruby Boxはクラス等の定義の分離/隔離のための機能を提供する、実験的機能です。Ruby Boxは環境変数として RUBY_BOX=1 を指定することで有効化できます。クラス名は Ruby::Box です。
Boxの中で読み込まれた定義はそのBox内に閉じた状態となります。Ruby Boxが隔離できる定義としては、既存クラスへのモンキーパッチ、グローバル変数やクラス変数の操作、クラスやモジュールの定義、そして.rbファイルや拡張ライブラリとして実装されたライブラリ類です。
Ruby Boxの主要なユースケースとしては、次のものが想定されています:
- テストのために何かの挙動を上書きするようなモンキーパッチを必要とするテストケースをBox内に閉じて実行すること
- WebアプリケーションをBox内で実行することで、Blue-Greenデプロイメントをプロセス内で、アプリケーションサーバ上で実行すること
- WebアプリケーションをBox内で実行することで、依存関係の更新時などに、一定期間並列で動かしてRubyコードを用いてレスポンス等を検証すること
- (未設計の)「パッケージAPI」のような新しい高レベルAPIを作るための低レベルAPIとしての機能を提供すること
“Ruby Box”の詳細については次のドキュメントを参照してください: Ruby::Box. [Feature #21311] [Misc #21385]
ZJIT
ZJIT は、YJIT の次世代として開発された新しい just-in-time(JIT)コンパイラです。ZJIT サポート付きで Ruby をビルドするには Rust 1.85.0 以降が必要で、–zjit を指定すると ZJIT が有効になります。
私たちが Ruby 向けに新しいコンパイラを開発しているのは、パフォーマンスの上限を引き上げ(より大きなコンパイル単位サイズと SSA IR を導入)つつ、より一般的なデザインであるメソッドコンパイラにすることで、外部からの貢献を促進したいからです。詳しくは ブログ記事 をご覧ください。
ZJITは通常の Ruby インタプリタより高速ですが、まだ YJIT ほど速くはありません。ZJIT をぜひ試してみて欲しいですが、現時点では本番環境へのデプロイは控えたほうがよいかもしれません。Ruby 4.1 の ZJIT にご期待ください。
Ractor の改善
Ruby で簡単に並列処理を行うための Ractor に多くの改善がありました。まず、Ractor::Port というクラスを加え、メッセージの送受信についのて問題を解決しました(ブログ記事)。また、Ractor.shareable_procによって、ProcをRactor間で共有しやすくしました。
性能面では、多くのデータ構造を改善し、グローバルロックに対する競合が大幅に減少し、並列処理性能を向上しました。また、Ractor 間で共有するデータを減らすことで、並列実行時の CPU キャッシュの衝突を減らしました。
Ruby 3.0 で experimental feature として導入されましたが、来年くらいには experimental を取りたいと思っています。
言語仕様の変更
-
*nilはnil.to_aを呼ばなくなりました。**nilがnil.to_hashを呼ばないのと同様です。[Feature #21047] -
行頭の論理二項演算子(
||、&&、and、or)は、ドット記法のように前の行を継続するようになりました。次のコードは同等です。if condition1 && condition2 ... end従来の書き方:
if condition1 && condition2 ... endif condition1 && condition2 ... end
コアクラスの更新
注: 特筆すべきクラス更新のみを記載しています。
-
Array
array.reverse_each.findより効率的な代替としてArray#rfindを追加しました。[Feature #21678]Enumerable#findをより効率的に実行するArray#findを追加しました。[Feature #21678]
-
Binding
-
Binding#local_variablesは番号付きパラメータを含めなくなりました。また、Binding#local_variable_get、Binding#local_variable_set、Binding#local_variable_defined?は番号付きパラメータを扱わないようになりました。[Bug #21049] -
番号付きパラメータおよび “it” パラメータにアクセスするために、
Binding#implicit_parameters、Binding#implicit_parameter_get、Binding#implicit_parameter_defined?を追加しました。[Bug #21049]
-
-
Enumerator
-
Enumerator.produceがオプションのキーワード引数sizeを受け付けるようになりました。サイズには整数、Float::INFINITY、ラムダなどの呼び出し可能オブジェクト、または不明を示すnilを指定できます。省略時はFloat::INFINITYです。# 無限列挙子 enum = Enumerator.produce(1, size: Float::INFINITY, &:succ) enum.size # => Float::INFINITY # サイズが既知/計算可能な有限列挙子 abs_dir = File.expand_path("./baz") # => "/foo/bar/baz" traverser = Enumerator.produce(abs_dir, size: -> { abs_dir.count("/") + 1 }) { raise StopIteration if it == "/" File.dirname(it) } traverser.size # => 4
-
-
ErrorHighlight
-
ArgumentErrorが発生した際に、メソッド呼び出し側(caller)とメソッド定義側(callee)の両方のコードスニペットを表示するようになりました。[Feature #21543]test.rb:1:in 'Object#add': wrong number of arguments (given 1, expected 2) (ArgumentError) caller: test.rb:3 | add(1) ^^^ callee: test.rb:1 | def add(x, y) = x + y ^^^ from test.rb:3:in '<main>'
-
-
Fiber
Kernel#raiseと同様にFiber#raise(cause:)引数をサポートしました。[Feature #21360]
-
Fiber::Scheduler
-
指定した例外でファイバを中断する
Fiber::Scheduler#fiber_interruptを追加しました。初期用途は、IO 操作が閉じられたときにブロッキング IO を待っているファイバを中断することです。[Feature #21166] -
シグナル例外が無効なときでもスケジューラが処理を続行できるよう、
Fiber::Scheduler#yieldを追加しました。[Bug #21633] -
非同期
IO#close用のFiber::Scheduler#io_closeフックを再導入しました。 -
IO 書き込みバッファを flush する際に
Fiber::Scheduler#io_writeを呼び出すようになりました。[Bug #21789]
-
-
File
- カーネルとファイルシステムが対応していれば、statx システムコール経由で Linux でも
File::Stat#birthtimeが利用可能になりました。[Feature #21205]
- カーネルとファイルシステムが対応していれば、statx システムコール経由で Linux でも
-
IO
-
IO.selectがタイムアウト引数としてFloat::INFINITYを受け付けるようになりました。[Feature #20610] -
|で始まるIOクラスメソッドによるプロセス生成という非推奨挙動を削除しました。[Feature #19630]
-
-
Kernel
-
Kernel#inspectは#instance_variables_to_inspectメソッドの有無を確認し、#inspect文字列に表示するインスタンス変数を制御できるようになりました。class DatabaseConfig def initialize(host, user, password) @host = host @user = user @password = password end private def instance_variables_to_inspect = [:@host, :@user] end conf = DatabaseConfig.new("localhost", "root", "hunter2") conf.inspect #=> #<DatabaseConfig:0x0000000104def350 @host="localhost", @user="root"> -
|で始まるKernel#openによるプロセス生成という非推奨挙動を削除しました。[Feature #19630]
-
-
Math
Math.log1pとMath.expm1を追加しました。[Feature #21527]
-
Pathname
- Pathname は default gem から Ruby のコアクラスに昇格しました。[Feature #17473]
-
Proc
Proc#parametersは匿名のオプション引数を[:opt, nil]ではなく[:opt]と表示するようになり、必須匿名引数の場合と整合しました。[Bug #20974]
-
Ractor
-
Ractor 間の通信のための新しい同期機構として
Ractor::Portクラスを追加しました。[Feature #21262]port1 = Ractor::Port.new port2 = Ractor::Port.new Ractor.new port1, port2 do |port1, port2| port1 << 1 port2 << 11 port1 << 2 port2 << 12 end 2.times{ p port1.receive } #=> 1, 2 2.times{ p port2.receive } #=> 11, 12Ractor::Portは次のメソッドを提供します。Ractor::Port#receiveRactor::Port#send(またはRactor::Port#<<)Ractor::Port#closeRactor::Port#closed?
この結果、
Ractor.yieldとRactor#takeは削除されました。 -
Ractor の終了待ちを行うために
Ractor#joinとRactor#valueを追加しました。Thread#join、Thread#valueに相当します。 -
Ractor#joinを実装するために内部で使われる低レベルインターフェイスとしてRactor#monitorとRactor#unmonitorを追加しました。 -
Ractor.selectは Ractor と Port のみを受け付けるようになりました。Ractor が与えられた場合は、その Ractor が終了すると戻ります。 -
各
Ractorはデフォルトポートを持ち、Ractor.send、Ractor.receiveで使用されるようになりました (Ractor#default_portを追加)。 -
Ractor#close_incomingとRactor#close_outgoingは削除されました。 -
共有可能な Proc / lambda を作るために
Ractor.shareable_procとRactor.shareable_lambdaを追加しました。[Feature #21550] [Feature #21557]
-
-
Range
-
Range#to_setはサイズチェックを行うようになり、終端のない範囲での問題を防ぎます。[Bug #21654] -
Range#overlap?は無限(非境界)範囲を正しく扱うようになりました。[Bug #21185] -
始点のない整数範囲での
Range#maxの挙動を修正しました。[Bug #21174] [Bug #21175]
-
-
Ruby
- Ruby に関する定数を含む新しいトップレベルモジュール
Rubyを定義しました。このモジュールは Ruby 3.4 で予約されており、今回正式に定義されました。[Feature #20884]
- Ruby に関する定数を含む新しいトップレベルモジュール
-
Ruby::Box
- 定義の分離を提供する新しい(実験的)機能です。詳細は doc/language/box.md を参照してください。[Feature #21311] [Misc #21385]
-
Set
-
Setは自動ロードされる stdlib クラスからコアクラスになりました。[Feature #21216] -
Set#inspectは配列リテラル風の簡潔な表示になりました(例:#<Set: {1, 2, 3}>ではなくSet[1, 2, 3])。[Feature #21389] -
Set#to_setとEnumerable#to_setへの引数指定は非推奨になりました。[Feature #21390]
-
-
Socket
Socket.tcpとTCPSocket.newが初回接続のタイムアウトを指定するキーワード引数open_timeoutを受け付けるようになりました。[Feature #21347]TCPSocket.newでユーザー指定タイムアウトが発生した場合、状況によりErrno::ETIMEDOUTまたはIO::TimeoutErrorが発生し得ましたが、今後は一貫してIO::TimeoutErrorを発生させます(ただしSocket.tcpでは同様の状況でErrno::ETIMEDOUTとなる場合があり、OS レベルのタイムアウトではいずれの場合もErrno::ETIMEDOUTが発生する可能性があります)。
-
String
-
Unicode を Version 17.0.0、Emoji を Version 17.0 に更新しました(Regexp にも適用)。[Feature #19908][Feature #20724][Feature #21275]
-
String#strip、strip!、lstrip、lstrip!、rstrip、rstrip!が*selectors引数を受け付けるようになりました。[Feature #21552]
-
-
Thread
Kernel#raiseと同様にThread#raise(cause:)引数をサポートしました。[Feature #21360]
Stdlib の更新
ここでは注目すべき機能変更のみを記載します。
その他の変更は以下のセクションに記載しています。また、前回バンドル版(Ruby 3.4.0)からの GitHub リリース履歴がある場合はそれも記載しています。
次の bundled gem が default gem から昇格しました。
- ostruct 0.6.3
- pstore 0.2.0
- 0.1.4 to v0.2.0
- benchmark 0.5.0
- logger 1.7.0
- rdoc 7.0.2
- win32ole 1.9.2
- 1.9.1 to v1.9.2
- irb 1.16.0
- reline 0.6.3
- readline 0.0.4
- fiddle 1.1.8
次のデフォルト gem を追加しました。
- win32-registry 0.1.2
次の default gem を更新しました。
- RubyGems 4.0.3
- bundler 4.0.3
- date 3.5.1
- delegate 0.6.1
- digest 3.2.1
- 3.2.0 to v3.2.1
- english 0.8.1
- 0.8.0 to v0.8.1
- erb 6.0.1
- error_highlight 0.7.1
- etc 1.4.6
- fcntl 1.3.0
- 1.2.0 to v1.3.0
- fileutils 1.8.0
- 1.7.3 to v1.8.0
- forwardable 1.4.0
- 1.3.3 to v1.4.0
- io-console 0.8.2
- 0.8.1 to v0.8.2
- io-nonblock 0.3.2
- io-wait 0.4.0
- 0.3.2 to v0.3.3, v0.3.5.test1, v0.3.5, v0.3.6, v0.4.0
- ipaddr 1.2.8
- json 2.18.0
- net-http 0.9.1
- openssl 4.0.0
- optparse 0.8.1
- pp 0.6.3
- 0.6.2 to v0.6.3
- prism 1.7.0
- psych 5.3.1
- resolv 0.7.0
- stringio 3.2.0
- strscan 3.1.6
- time 0.4.2
- 0.4.1 to v0.4.2
- timeout 0.6.0
- uri 1.1.1
- weakref 0.1.4
- 0.1.3 to v0.1.4
- zlib 3.2.2
- 3.2.1 to v3.2.2
次の bundled gem を更新しました。
- minitest 6.0.0
- power_assert 3.0.1
- rake 13.3.1
- test-unit 3.7.3
- rexml 3.4.4
- rss 0.3.2
- 0.3.1 to 0.3.2
- net-ftp 0.3.9
- 0.3.8 to v0.3.9
- net-imap 0.6.2
- net-smtp 0.5.1
- 0.5.0 to v0.5.1
- matrix 0.4.3
- 0.4.2 to v0.4.3
- prime 0.1.4
- 0.1.3 to v0.1.4
- rbs 3.10.0
- 3.8.0 to v3.8.1, v3.9.0.dev.1, v3.9.0.pre.1, v3.9.0.pre.2, v3.9.0, v3.9.1, v3.9.2, v3.9.3, v3.9.4, v3.9.5, v3.10.0.pre.1, v3.10.0.pre.2, v3.10.0
- typeprof 0.31.1
- debug 1.11.1
- 1.11.0 to v1.11.1
- base64 0.3.0
- 0.2.0 to v0.3.0
- bigdecimal 4.0.1
- drb 2.2.3
- 2.2.1 to v2.2.3
- syslog 0.3.0
- 0.2.0 to v0.3.0
- csv 3.3.5
- repl_type_completor 0.1.12
RubyGems と Bundler
RubyGems と Bundler は Version 4 が同梱されています。詳細は次のリンクを参照してください。
- Upgrading to RubyGems/Bundler 4 - RubyGems Blog
- 4.0.0 Released - RubyGems Blog
- 4.0.1 Released - RubyGems Blog
- 4.0.2 Released - RubyGems Blog
- 4.0.3 Released - RubyGems Blog
サポートプラットフォーム
-
Windows
- _MSC_VER 1900 より古い MSVC をサポート対象外としました。つまり Visual Studio 2015 以降が必須になります。
互換性に関する注意
-
Ractor::Port追加に伴い、Ractor から次のメソッドを削除しました。Ractor.yieldRactor#takeRactor#close_incomingRactor#close_outgoing
-
ObjectSpace._id2refは非推奨になりました。[Feature #15408] -
Process::Status#&とProcess::Status#>>を削除しました(Ruby 3.3 で非推奨)。[Bug #19868] -
$SAFEのパスチェック(Ruby 2.7 で削除)に使われ、既に非推奨だったrb_path_checkを削除しました。[Feature #20971] -
“wrong number of arguments” の
ArgumentErrorのバックトレースに、受け手のクラス/モジュール名が含まれるようになりました(例:barではなくFoo#bar)。[Bug #21698] -
バックトレースに
internalフレームが表示されなくなりました。C 実装メソッドも、他の C 実装と同様に Ruby ソースファイル上にあるかのように表示されます。[Bug #20968]変更前:
ruby -e '[1].fetch_values(42)' <internal:array>:211:in 'Array#fetch': index 42 outside of array bounds: -1...1 (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 -e:1:in '<main>'変更後:
$ ruby -e '[1].fetch_values(42)' -e:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError) from -e:1:in '<main>'
Stdlib 互換性の注意
-
CGI ライブラリは default gem から除外されました。現在は次のメソッド向けに
cgi/escapeのみ提供します。CGI.escape/CGI.unescapeCGI.escapeHTML/CGI.unescapeHTMLCGI.escapeURIComponent/CGI.unescapeURIComponentCGI.escapeElement/CGI.unescapeElement
-
Setが stdlib からコアクラスへ移動したため、set/sorted_set.rbを削除し、SortedSetは自動ロードされる定数ではなくなりました。利用する場合はsorted_setgem をインストールし、require 'sorted_set'してください。[Feature #21287] -
Net::HTTP
- ボディ(本文)を持つリクエスト(例:POST、PUT)において、Content-Type ヘッダーが明示的に設定されていない場合に、デフォルトで application/x-www-form-urlencoded を自動設定する挙動が削除されました。もしアプリケーションがこの自動設定に依存していた場合、今後は Content-Type ヘッダーなしでリクエストが送信されることになり、特定のサーバーとの互換性が失われる可能性があります。 [GH-net-http #205]
C API の更新
-
IO
rb_thread_fd_closeは非推奨になり、何もしなくなりました。C 拡張でファイルディスクリプタを Ruby コードに公開する必要がある場合は、RUBY_IO_MODE_EXTERNALを使ってIOインスタンスを作成し、rb_io_close(io)で閉じてください(これにより、その IO 上のすべての保留操作が割り込まれ、完了を待ちます)。ディスクリプタを直接閉じても保留操作は割り込まれず、未定義動作を招く可能性があります。言い換えると、同じファイルディスクリプタを共有する 2 つのIOオブジェクトの片方を閉じても、もう一方には影響しません。[Feature #18455]
-
GVL
rb_thread_call_with_gvlは GVL の有無にかかわらず動作するようになりました。これにより gem はruby_thread_has_gvl_pを確認せずに済みますが、GVL の扱いには引き続き注意してください。[Feature #20750]
-
Set
-
Setの C API を追加しました。次のメソッドをサポートします。[Feature #21459]rb_set_foreachrb_set_newrb_set_new_caparb_set_lookuprb_set_addrb_set_clearrb_set_deleterb_set_size
-
実装の改善
Class#new(例:Object.new)が全般的に高速化され、特にキーワード引数を渡す場合に効果があります。YJIT と ZJIT にも取り込まれました。[Feature #21254]- サイズプールの異なる GC ヒープを独立して成長させるようにし、一部のプールだけに長寿命オブジェクトがある場合のメモリ使用量を削減しました。
- 大きなオブジェクトページでの GC スイープが高速化されました。
- “Generic ivar” オブジェクト(String、Array、
TypedDataなど)は、新しい内部 “fields” オブジェクトを使ってインスタンス変数アクセスを高速化します。 - GC は内部の
id2refテーブルを初回使用まで保持しないようにし、object_idの割り当てと GC スイープを高速化しました。 - Class / Module オブジェクトでの
object_idとhashが高速化されました。 - より大きな多倍長整数でも可変幅アロケーションにより埋め込みのまま保持できるようになりました。
Random、Enumerator::Product、Enumerator::Chain、Addrinfo、StringScanner、および一部内部オブジェクトが書き込みバリア保護され、GC のオーバーヘッドを削減します。
Ractor
Ractor をより安定・高性能・実用的にするため多くの改善を行いました。これらにより Ractor 実装は実験的ステータスを脱する段階に近づいています。
- パフォーマンス改善
- 凍結文字列とシンボルテーブルが内部でロックフリーのハッシュセットを使用します。[Feature #21268]
- メソッドキャッシュの参照で多くの場合ロックを回避します。
- クラス(および generic ivar)のインスタンス変数アクセスが高速化され、ロックを避けます。
- Ractor ごとのカウンタを用いてオブジェクト割り当てでの CPU キャッシュ競合を回避します。
- スレッドローカルカウンタを用いて xmalloc/xfree での CPU キャッシュ競合を回避します。
- 多くの場合
object_id取得でロックを回避します。
- バグ修正と安定性
- Ractor と Thread の併用で起こり得るデッドロックを修正しました。
- Ractor 内での require / autoload の問題を修正しました。
- Ractor 間のエンコーディング/トランスコード問題を修正しました。
- GC 操作やメソッド無効化に関する競合を修正しました。
- Ractor 起動後にプロセスを fork する際の問題を修正しました。
- Ractor 環境下で GC の割り当てカウントが正確になりました。
- GC 後に TracePoint が動作しない問題を修正しました。[Bug #19112]
JIT
- ZJIT
- メソッドベースの実験的 JIT コンパイラ を導入しました。利用可能な場合、ZJIT は
--zjitオプションまたはRubyVM::ZJIT.enableを呼び出すことで実行時に有効化できます。 Ruby をビルドする場合、ZJIT サポートを含めるには Rust 1.85.0 以降が必要です。 - Ruby 4.0.0 時点で ZJIT はインタプリタより高速ですが、まだ YJIT には及びません。ZJIT の試用を推奨しますが、現時点では本番利用を推奨しません。
- 目標は Ruby 4.1 で ZJIT を YJIT より高速かつ本番対応にすることです。
- メソッドベースの実験的 JIT コンパイラ を導入しました。利用可能な場合、ZJIT は
- YJIT
RubyVM::YJIT.runtime_stats- デフォルトビルドでは
ratio_in_yjitは利用できなくなりました。configureで--enable-yjit=statsを付け、--yjit-statsで有効化してください。 - すべてのコードが TracePoint により無効化された回数を表す
invalidate_everythingをデフォルト統計に追加しました。
- デフォルトビルドでは
RubyVM::YJIT.enableにmem_size:とcall_threshold:オプションを追加しました。
- RJIT
--rjitを削除しました。サードパーティ JIT API の実装は ruby/rjit リポジトリに移します。
より詳細な情報は NEWS か commit logs を参照してください。
これらの変更により、Ruby 3.4.0から 3889 ファイルが変更され、 230769 行が追加され、 297003 行が削除されました!
メリークリスマス、良いお年を、そして Happy Hacking with Ruby 4.0!
Download
-
https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.0.tar.gz
SIZE: 23955109 SHA1: 754e39e9ad122e1b6deaed860350bac133a35ed3 SHA256: 2e8389c8c072cb658c93a1372732d9eac84082c88b065750db1e52a5ac630271 SHA512: 688254e939b197d564e896fb951bc1abf07142f489e91c5ed0b11f68f52d6adb6b1f86616fe03f1f0bb434beeef7e75e158b9c616afb39bb34403b0b78d2ee19 -
https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.0.tar.xz
SIZE: 18008368 SHA1: 05ec670e86f84325c5353ef2f2888e53b6adc602 SHA256: a72bacee9de07283ebc19baa4ac243b193129f21aa4e168c7186fb1fe7d07fe1 SHA512: 2d5b2e566eaf70a5f3ea6ce6afc0611c0415de58a41336ef7a0b855c9a91eda9aa790a5f8b48e40a1eb9d50f8ea0f687216e617f16c8d040a08474f3116518a4 -
https://cache.ruby-lang.org/pub/ruby/4.0/ruby-4.0.0.zip
SIZE: 29253204 SHA1: 0b69f89d1d140157251c0d3a6032f6c45cdf81e8 SHA256: 70cb1bf89279b86ab9a975d504607c051fc05ee03e311d550a5541b65e373455 SHA512: a72e076ef618c0aeb9d20cf22e6fb12fda36809c0064ef0f98153b95a0bac257ef606342444a38f992c4594bf376a4d264686cf597463aa6f111220798784302
What is Ruby
Rubyはまつもとゆきひろ (Matz) によって1993年に開発が始められ、今もオープンソースソフトウェアとして開発が続けられています。Rubyは様々なプラットフォームで動き、世界中で、特にWebアプリケーション開発のために使われています。
最近のニュース
サイトのアイデンティティの再設計
サイトの包括的なデザインのアップデートを発表できることを嬉しく思います。今回の更新ではTaeko Akatsukaさんにデザインを担当していただきました。
Posted by Hiroshi SHIBATA on 22 Dec 2025
Ruby 4.0.0 preview3 リリース
Ruby 4.0.0-preview3 が公開されました。
Posted by naruse on 18 Dec 2025
Ruby 4.0.0 preview2 リリース
Ruby 4.0.0-preview2 が公開されました。Ruby 4.0では、Unicodeバージョンの17.0.0へのアップデートなど様々な改善が行われています。
Posted by naruse on 17 Nov 2025
RubyGemsリポジトリ所有権の移行
Rubyコミュニティの皆様へ
Posted by matz on 17 Oct 2025