Ruby 3.2 - Proc

Ruby 3.2 アドベントカレンダーの20日目の記事です。

qiita.com


Proc

Proc#dup が元のオブジェクトと同じクラスのオブジェクトを返す

Bug #17545: Calling dup on a subclass of Proc returns a Proc and not the subclass - Ruby master - Ruby Issue Tracking System

Ruby 1.9 以降、Proc のサブクラスを dup するとサブクラスではなく Proc オブジェクトが返ってたのが、ちゃんとサブクラスオブジェクトが返るようになった。

class Hoge < Proc
  def inspect
    "instance of Hoge"
  end
end
pp Hoge.new{}.dup
#=> <instance of Hoge>
# Ruby 3.1 までは #<Proc:0x00007f82af54ccf0 hoge.rb:6>

Proc#parameters に lambda オプション追加

Feature #15357: Proc#parameters returns incomplete type information - Ruby master - Ruby Issue Tracking System

Proc#parameterslambda が真の場合は lambda とみなしたパラメータを返し、偽の場合は proc とみなしたパラメータを返す。

pr = proc{|x, y=0|}
pp pr.parameters
#=> [[:opt, :x], [:opt, :y]]   proc なので x も y もオプション
pp pr.parameters(lambda: true)
#=> [[:req, :x], [:opt, :y]]   lambda とみなすので x は必須
pp pr.parameters(lambda: false)
#=> [[:opt, :x], [:opt, :y]]   proc と同じ

lm = lambda{|x, y=0|}
pp lm.parameters
#=> [[:req, :x], [:opt, :y]]   lambda なので x は必須
pp lm.parameters(lambda: true)
#=> [[:req, :x], [:opt, :y]]   lambda と同じ
pp lm.parameters(lambda: false)
#=> [[:opt, :x], [:opt, :y]]   proc とみなすので x も y もオプション

Ruby 3.2 - Process / Socket / UNIXSocket

Ruby 3.2 アドベントカレンダーの19日目の記事です。

qiita.com


Process

Process に定数追加

FreeBSD で Process::RLIMIT_NPTS が追加された。FreeBSD 使ってないからよくわからん。

Socket

Socket に定数追加

Socket に定数が追加された。

Socket::SO_INCOMING_CPU, Socket::SO_INCOMING_NAPI_ID, Socket::SO_RTABLE, Socket::SO_SETFIB, Socket::SO_USER_COOKIE, Socket::TCP_KEEPALIVE, Socket::TCP_CONNECTION_INFO

Ubuntu 22.10 で有効なのは Socket::SO_INCOMING_CPUSocket::SO_INCOMING_NAPI_ID だけっぽい。

UNIXSocket

Feature #19135: Support UNIXSocket on Windows - Ruby master - Ruby Issue Tracking System

最近の Windows は UNIX ソケットをサポートしたらしい。 ということで、Windows でも UNIXSocket, File.socket?, File::Stat#socket? がサポートされるようになった。

Windows 使ってないから試してない。

Ruby 3.2 - Integer / Set

Ruby 3.2 アドベントカレンダーの18日目の記事です。

qiita.com


Integer

Integer#ceildiv 追加

Feature #18809: Add Numeric#ceildiv - Ruby master - Ruby Issue Tracking System

商を切り上げる割り算の Integer#ceildiv が追加された。

123.ceildiv(10)  #=> 13

nビットを表現するのに何バイト必要かを計算するときに (n-1)/8+1 とかしてたんだけど、n.ceildiv(8) と簡単に書けるようになって便利。

Set

require しなくてもよくなった

Feature #16989: Sets: need ♥️ - Ruby master - Ruby Issue Tracking System

require 'set' しなくても Set が使えるようになった。便利。

Ruby 3.2 - Module

Ruby 3.2 アドベントカレンダーの17日目の記事です。

qiita.com


Module

Module#const_added

Feature #17881: Add a Module#const_added callback - Ruby master - Ruby Issue Tracking System

Module#const_added が追加された。定数が追加されたときに実行されるメソッド。 モジュールやクラスが追加されたときも実行される。

module Hoge
  def self.const_added(const)
    puts "#{const.inspect} is added"
  end
end

Hoge::CONST = 1
#=> :CONST is added

class Hoge::Fuga
end
#=> :Fuga is added

Module#undefined_instance_methods

Feature #12655: Accessing the method visibility - Ruby master - Ruby Issue Tracking System

Module#undefined_instance_methods が追加された。undef されたメソッドの一覧が返る。

class Hoge
  def hoge
  end
end
Hoge.undefined_instance_methods  #=> []

class Hoge
  undef hoge
end
Hoge.undefined_instance_methods  #=> [:hoge]

Ruby 3.2 - リファインメント

Ruby 3.2 アドベントカレンダーの16日目の記事です。

qiita.com


リファインメント

Module#used_refinements

Feature #14332: Module.used_refinements to list refinement modules - Ruby master - Ruby Issue Tracking System

Module.used_refinements が追加された。現在のスコープで有効な Refinement オブジェクトを返す。

module Hoge
  refine Integer do
  end
end

module Fuga
  refine String do
  end
end

Module.used_refinements  #=> []
using Hoge
Module.used_refinements  #=> [#<refinement:Object@Hoge>]
using Fuga
Module.used_refinements  #=> [#<refinement:Object@Fuga>, #<refinement:Object@Hoge>]

Module#refinements と Refinement#refined_class

Feature #12737: Module#defined_refinements - Ruby master - Ruby Issue Tracking System

Module#refinements はモジュール内で定義されている Refinement オブジェクトを返す。

module Hoge
  refine Integer do
  end
  refine String do
  end
end

Hoge.refinements  #=> [#<refinement:Integer@Hoge>, #<refinement:String@Hoge>]

Refinement#refined_class はリファインされてるクラスを返す。

module Hoge
  refine Integer do
  end
  refine String do
  end
end

r1, r2 = Hoge.refinements
r1.refined_class  #=> Integer
r2.refined_class  #=> String

Ruby 3.2 - Hash

Ruby 3.2 アドベントカレンダーの15日目の記事です。

qiita.com


Hash

デフォルト値を持つ Hash オブジェクトが空の場合に Hash#shift が返す値が変わった

Bug #16908: Strange behaviour of Hash#shift when used with default_proc. - Ruby master - Ruby Issue Tracking System

Hash オブジェクトが空の場合、Hash#shift は nil を返すけど、Hash オブジェクトがデフォルト値を持っていた場合はそのデフォルト値を返すようになっていた。

h = Hash.new(123)  #=> {}
h[:hoge]  #=> 123
h.shift   #=> 123

これは変だってことで、Ruby 3.2 ではデフォルト値があっても nil を返すようになった。

h = Hash.new(123)  #=> {}
h[:hoge]  #=> 123
h.shift   #=> nil

Ruby 3.2 - Enumerator

Ruby 3.2 アドベントカレンダーの14日目の記事です。

qiita.com


Enumerator

Enumerator::Product クラスと Enumerator.product メソッド追加

Feature #18685: Enumerator.product: Cartesian product of enumerables - Ruby master - Ruby Issue Tracking System

Array#product は自身の配列オブジェクトと引数の配列を組み合わせた配列の配列を返す。 こんな感じ:

[1,2,3].product([4,5])
#=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
[1,2].product([3,4],[5,6])
#=> [[1, 3, 5],
#    [1, 3, 6],
#    [1, 4, 5],
#    [1, 4, 6],
#    [2, 3, 5],
#    [2, 3, 6],
#    [2, 4, 5],
#    [2, 4, 6]]

Enumerator.product は配列だけじゃなくて Enumerable オブジェクトでこれと同じような動きをする。戻り値も配列じゃなくて Enumerator の一種の Enumerator::Product を返す。

e = Enumerator.product(1..3, [4,5])
#=> #<Enumerator::Product: ...>
e.to_a
#=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

Enumerator.product()Enumerator::Product.new() と同じ。

e = Enumerator::Product.new(1..3, [4,5])
#=> #<Enumerator::Product: ...>
e.to_a
#=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

Ruby 3.2 - MatchData

Ruby 3.2 アドベントカレンダーの13日目の記事です。

qiita.com


MatchData

MatchData#byteoffset

Feature #13110: Byte-based operations for String - Ruby master - Ruby Issue Tracking System

MatchData は正規表現に適合した文字列を表すクラス。 MatchData#offset で適合した全体や括弧の部分の範囲を文字単位で取得できる。

s = "あいう123えおabcかきく"
m = s.match(/(\w+)\W*(\w+)/)  #=> #<MatchData "123えおabc" 1:"123" 2:"abc">
m.offset(0)  #=> [3, 11]   正規表現全体に適合したのは s[3...11]
m.offset(1)  #=> [3, 6]    最初の括弧に適合した '123' は s[3...6]
m.offset(2)  #=> [8, 11]   次の括弧に適合した 'abc' は s[8...11]

Ruby 3.2 でこれをバイト単位で取り出せるようにした MatchData#byteoffset が追加された。

m.byteoffset(0)  #=> [9, 21]    正規表現全体に適合したのは s.b[9...21]
m.byteoffset(1)  #=> [9, 12]    最初の括弧に適合した '123' は s.b[9...12]
m.byteoffset(2)  #=> [18, 21]   次の括弧に適合した 'abc' は s.b[18...21]

MatchData#deconstruct / MatchData#deconstruct_keys

Feature #18821: Expose Pattern Matching interfaces in core classes - Ruby master - Ruby Issue Tracking System

Ruby 3.2 で MatchData#deconstructMatchData#deconstruct_keys が追加された。

MatchData#deconstructMatchData#captures のエイリアス。

s = "あいう123えおabcかきく"
m = s.match(/(\w+)\W*(\w+)/)  #=> #<MatchData "123えおabc" 1:"123" 2:"abc">
m.deconstruct  #=> ["123", "abc"]

正規表現内の括弧には名前をつけることができて MatchData#[]MatchData#named_captures で参照できる。

m = s.match(/(?<a>\w+)\W*(?<b>\w+)/)  #=> #<MatchData "123えおabc" a:"123" b:"abc">
m['a']  #=> "123"
m['b']  #=> "abc"
m.named_captures  #=> {"a"=>"123", "b"=>"abc"}

MatchData#deconstruct_keys はシンボルで名前を指定して参照できる。nil を指定するとすべての名前付き括弧が参照できる。

m.deconstruct_keys(nil)   #=> {:a=>"123", :b=>"abc"}
m.deconstruct_keys([:b])  #=> {:b=>"abc"}

deconstructdeconstruct_keys という名前でピンときた人もいると思うけど、これによって MatchData をパターンマッチで使えるようになるということらしい。

IP_REGEX = /
  (?<first_octet>\d{1,3})\.
  (?<second_octet>\d{1,3})\.
  (?<third_octet>\d{1,3})\.
  (?<fourth_octet>\d{1,3})
/x

'192.168.1.1'.match(IP_REGEX) in {first_octet: '192', fourth_octet: '1'}  #=> true

自分はピンとこなかった。パターンマッチよくわからん。

Ruby 3.2 - Regexp

Ruby 3.2 アドベントカレンダーの12日目の記事です。

qiita.com


Regexp

Regexp.new に文字列でオプション指定可能

Feature #18788: Support passing Regexp options as String to Regexp.new - Ruby master - Ruby Issue Tracking System

Ruby の正規表現リテラルは /hoge/im みたいに後ろにオプションをつけられるんだけど、Regexp.new の場合は、

Regexp.new('hoge', Regexp::IGNORECASE|Regexp::MULTILINE)  #=> /hoge/mi

みたいに書かないといけなかった。めんどくさい。

文字列で指定して、

Regexp.new('hoge', 'i')  #=> /hoge/i

お、できるじゃん! って思うかもしれないけどこれは罠で、第2引数が数値以外で真の場合は i になる。

Regexp.new('hoge', 'm')  #=> /hoge/i

Ruby 3.2 では文字列でも指定できるようになった。

Regexp.new('hoge', 'im')  #=> /hoge/mi

便利。

Regexp.timeout= 追加

Feature #17837: Add support for Regexp timeouts - Ruby master - Ruby Issue Tracking System

ReDoS 対策として、正規表現のパターンマッチをタイムアウトさせることができるようになった。

Regexp.timeout = 0.000001
"a"*1000+"X" =~ /\A(a+)+\z/  #=> regexp match timeout (Regexp::TimeoutError)

正規表現のマッチングアルゴリズムの改善

Feature #19104: Introduce the cache-based optimization for Regexp matching - Ruby master - Ruby Issue Tracking System

上の正規表現のマッチングは Ruby 3.2 だとタイムアウトを設定しなくても一瞬で終わるけど、Ruby 3.1 だと終わらない。

"a"*30+"X" =~ /\A(a+)+\z/

これでも 13秒くらいかかる。Ruby 3.2 でアルゴリズムが変更されt大幅に改善されたらしい。

NEWS.md には書いてないけど、3.2.0 RC 1 リリースのお知らせには書いてあった。

Ruby 3.2 - String / Encoding / ユニコード

Ruby 3.2 アドベントカレンダーの11日目の記事です。

qiita.com


String

String#byteindex / String#byterindex

Feature #13110: Byte-based operations for String - Ruby master - Ruby Issue Tracking System

String#byteindex, String#byterindex が追加された。

#index, #rindex は文字単位だけど、#byteindex, #byterindex はバイト単位のインデックスを返す。

'じゅげむじゅげむ'.index('')      #=> 2
'じゅげむじゅげむ'.rindex('')     #=> 6
'じゅげむじゅげむ'.byteindex('')  #=> 6
'じゅげむじゅげむ'.byterindex('') #=> 18

String#bytesplice

Feature #18598: Add String#bytesplice - Ruby master - Ruby Issue Tracking System

String#bytesplice が追加された。 文字列のバイト位置の文字を置換する。

s = 'abcdefg'
s.bytesplice(3, 3, '12345')  #=> "12345"
# 'def' が '12345' に置換される
s  #=> "abc12345g"
s = 'あいうえお'
s.bytesplice(3, 3, '12345')  #=> "12345"
# 'い' が '12345' に置換される
s  #=> "あ12345うえお"

マルチバイト文字の場合は文字境界にあわないとエラーになる。

s = 'あいうえお'
s.bytesplice(4, 1, 'x')
#=> offset 4 does not land on character boundary (IndexError)

Encoding

Feature #18949: Deprecate and remove replicate and dummy encodings - Ruby master - Ruby Issue Tracking System

Encoding#replicate が 非推奨になり、3.3 で削除される予定になった。

-w つきで実行すると警告が出る。

% ruby -w -e 'Encoding::UTF_8.replicate("hoge")'
-e:1: warning: Encoding#replicate is deprecated and will be removed in Ruby 3.3; use the original encoding instead

Encoding#replicate なんて使ったことないから、何のために存在していたのかわかってない。

Unicode 15.0.0 / Emoji 15.0

Feature #18639: Update Unicode data to Unicode Version 15.0.0 - Ruby master - Ruby Issue Tracking System

Unicode 15.0.0 と Emoji 15.0 に対応した。Ruby 3.1 は Unicode 13.0.0 と Emoji 13.0 だった。

Ruby 3.1

'😀🫠😇🫨'.inspect  #=> "😀\u{1FAE0}😇\u{1FAE8}"

Ruby 3.2

'😀🫠😇🫨'.inspect  #=> "😀🫠😇🫨"

Ruby 3.2 - Data / Struct

Ruby 3.2 アドベントカレンダーの10日目の記事です。

qiita.com


Data

Feature #16122: Data: simple immutable value object - Ruby master - Ruby Issue Tracking System

Ruby 3.2 で Data クラスが新設された。Struct とほぼ同じなんだけどオブジェクト作った後に値を変更することができない。

Data をそのまま使うんじゃなくて、Data.defineData の子クラスを作って使う。

Hoge = Data.define(:name, :value)
hoge = Hoge.new('abc', 123)        #=> #<data Hoge name="abc", value=123>
Hoge.new(name: 'abc', value: 123)  # これでも同じ
Hoge['abc', 123]                   # これでも同じ

hoge.name   #=> "abc"
hoge.value  #=> 123
hoge.name = 'xyz'  #=> undefined method `name=' for #<data Hoge name="abc", value=123> (NoMethodError)

StructStruct.new で子クラスを作ったんだけど、字面的に new はイマイチじゃない?ってことで Data.define になったらしい。

なお、Data.new は NoMethodError になる。

Struct

Feature #16806: Struct#initialize accepts keyword arguments too by default - Ruby master - Ruby Issue Tracking System

Struct.new で構造体クラスを作成できる。

Hoge = Struct.new(:abc, :xyz)
hoge = Hoge.new(123, 456)
hoge.abc  #=> 123
hoge.xyz  #=> 456

このようにして作成されたクラスは Ruby 3.1 ではキーワード引数では初期化できない。Hash として第1引数に設定される。warning も出る。

hoge = Hoge.new(abc: 123, xyz: 456)
#=> warning: Passing only keyword arguments to Struct#initialize will behave differently from Ruby 3.2. Please use a Hash literal like .new({k: v}) instead of .new(k: v).
hoge.abc  #=> {:abc=>123, :xyz=>456}
hoge.xyz  #=> nil

Struct.newkeyword_init を指定するとキーワード引数で初期化できるクラスを作成する。ただし位置引数では指定できない。

Hoge = Struct.new(:abc, :xyz, keyword_init: true)
hoge = Hoge.new(abc: 123, xyz: 456)
hoge.abc  #=> 123
hoge.xyz  #=> 456
hoge = Hoge.new(123, 456)
#=> wrong number of arguments (given 2, expected 0) (ArgumentError)

Ruby 3.2 から keyword_init を指定しなくてもよくなった。位置引数でもキーワード引数でもどちらでも初期化できる。

Hoge = Struct.new(:abc, :xyz)
Hoge.new(123, 456)
#=> #<struct Hoge abc=123, xyz=456>
Hoge.new(abc: 123, xyz: 456)
#=> #<struct Hoge abc=123, xyz=456>

たぶん新しく作られた Data に合わせたのかな。便利。

Ruby 3.2 - Class

Ruby 3.2 アドベントカレンダーの9日目の記事です。

qiita.com


Class

Class#attached_object 追加

Feature #12084: Class#instance - Ruby master - Ruby Issue Tracking System

Ruby では、オブジェクトのクラスには存在しないメソッドをオブジェクト専用に定義できる。

class Hoge
end

hoge1 = Hoge.new
hoge2 = Hoge.new

def hoge1.fuga
end

hoge1.fuga
hoge2.fuga  #=> undefined method `fuga' for #<Hoge:0x00007f4174ff6830> (NoMethodError)

上の例では Hoge クラスのオブジェクト hoge1 には fuga があるけど、同じ Hoge クラスのオブジェクトの hoge2 には fuga が無いのでエラーとなる。

普通はメソッドはクラスに定義されるものなんだけど、fugahoge1オブジェクトに直接定義されてるように見える。 けど、実は内部的には各オブジェクトには無名のクラスがあってそこにメソッドが定義されてる。 そのクラスを特異クラスといって、singleton_class で取り出すことができる。

hoge1_s_c = hoge1.singleton_class  #=> #<Class:#<Hoge:0x00007ff418c969e0>>
hoge2_s_c = hoge2.singleton_class  #=> #<Class:#<Hoge:0x00007ff418c96968>>

名前がついてなのでわかりにくいけど、hoge1_s_choge2_s_c の値が違うので別のものだとわかる。 表示結果から Hoge クラスのオブジェクトについてる特異クラスであることがわかる。

そのクラスに定義されてるメソッドの中に fuga があるのがわかる。

hoge1_s_c.instance_methods.include?(:fuga)  #=> true
hoge2_s_c.instance_methods.include?(:fuga)  #=> false

で、Ruby 3.1 まではこの特異クラスに対応するオブジェクトは Ruby 的に綺麗に取り出す方法がなかった。

Ruby 3.2 では attached_object というメソッドで取り出すことができるようになった。

hoge1_s_c.attached_object  #=> #<Hoge:0x00007ff418c969e0>
hoge1_s_c.attached_object == hoge1  #=> true
hoge2_s_c.attached_object  #=> #<Hoge:0x00007ff418c96968>
hoge2_s_c.attached_object == hoge2  #=> true

使いどころは自分はよくわかってない。

なお、特異クラスではないクラスで attached_object を呼ぶとエラーになる。

Hoge.attached_object  #=> `Hoge' is not a singleton class (TypeError)

Ruby 3.2 - IO / FileUtils

Ruby 3.2 アドベントカレンダーの8日目の記事です。

qiita.com


IO

IO#timeout 追加

Feature #18630: Introduce general IO#timeout and IO#timeout= for blocking operations. - Ruby master - Ruby Issue Tracking System

IO#timeout でタイムアウトを設定できるようになった。

$stdin.timeout = 1
gets
#=> Blocking operation timed out! (IO::TimeoutError)
r, w = IO.pipe
w.timeout = 1
loop{w.write("hoge"*100)}
#=> Blocking operation timed out! (IO::TimeoutError)

Timeout.timeout とかを使わなくてもよくて便利。 Timeout.timeout は使うとスレッドを消費してしまってコストが高かったり、例外の扱いが特殊だったりするので。

IO#wait / IO#wait_readable / IO#wait_writable が組み込みになった

これ書いてて気づいたんだけど、IO#wait* メソッドが組み込みになってた。NEWS には書いてないな。 Ruby 3.1 までは require 'io/wait' しないといけなかった。

これはこれで便利。

FileUtils

FileUtils.ln_s に relative オプション追加

Feature #18925: Add FileUtils.ln_sr to create symbolic links relative to link location - Ruby master - Ruby Issue Tracking System

FileUtils には Unix のファイル操作系コマンドに似たメソッドが含まれてる。 FileUtils.ln_sln -s コマンドのようにシンボリックリンクを作成する。

require 'fileutils'
FileUtils.ln_s('/tmp/a/b/c', 'hoge')
puts File.readlink('hoge')  #=> "/tmp/a/b/c"

ln -s コマンドは普通は第1引数に指定したパスをそのまま使うけど、

% cd /tmp/a/b
% ln -s /tmp/a/b/c hoge
% ls -l hoge
lrwxrwxrwx 1 tommy tommy 10 126 22:06 hoge -> /tmp/a/b/c

ln -s-r オプションを追加すると第2引数のファイルらの相対パスが使われる。

% cd /tmp/a/b
% ln -sr /tmp/a/b/c hoge
% ls -l hoge
lrwxrwxrwx 1 tommy tommy 10 126 22:06 hoge -> c

FileUtils.ln_s にも -r と同じように振る舞う relative オプションが追加された。

require 'fileutils'
FileUtils.ln_s('/tmp/a/b/c', 'hoge', relative: true)
puts File.readlink('hoge')  #=> "c"

これと同じ振る舞いをする ln_sr メソッドも追加された。

require 'fileutils'
FileUtils.ln_sr('/tmp/a/b/c', 'hoge')
puts File.readlink('hoge')  #=> "c"

Ruby 3.2 - Coverage

Ruby 3.2 アドベントカレンダーの7日目の記事です。

qiita.com

Ruby 3.2.0 RC1 がリリースされたので、ネタ元を Ruby 3.2 RC1 の NEWS.md に変更。

6日目までに書いた内容は特に変更なさそう。


Coverage

eval でもカバレッジデータを取得可能

Feature #19008: Introduce coverage support for eval. - Ruby master - Ruby Issue Tracking System

eval: true を指定すると eval したときでもカバレッジデータを取得できるようになった。

require 'coverage'
Coverage.start(lines: true, eval: true)
s = <<EOS
10.times do |i|  # ここは1回
  if i.odd?      # ここは10回
    1            # ここは5回
  else
    2            # ここは5回
  end
end
EOS
eval s, nil, 'hoge'
pp Coverage.result
#=> {"hoge"=>{:lines=>[1, 10, 5, nil, 5, nil, nil]}}

便利。

Coverage.supported? 追加

Bug #19026: Add Coverage.supported?(x) to detect support for eval coverage flag. - Ruby master - Ruby Issue Tracking System

Coverage がサポートしてる機能を検査できる。

require 'coverage'
pp Coverage.supported?(:eval)  #=> true
pp Coverage.supported?(:hoge)  #=> false

Ruby 3.2 - インストール

Ruby 3.2 アドベントカレンダーの6日目の記事です。

qiita.com


インストール

libyaml と libffi が同梱されない

Feature #18571: Removed the bundled sources from release package after Ruby 3.2 - Ruby master - Ruby Issue Tracking System

libyaml と libffi ライブラリが同梱されなくなったので、OS に libyaml-dev や libffi-dev 等がインストールされてないと、psych と fiddle ライブラリがインストールされない。

これらのライブラリが必要な場合は、configure 時に --with-ext=psych,fiddle,+ をつけておいた方がいいかも。インストール時にエラーになって気づけるので。

YJIT に Rust が必要

Feature #18481: Porting YJIT to Rust (request for feedback) - Ruby master - Ruby Issue Tracking System

YJIT に Rust が必要になったので、Rust が入ってない環境でビルドすると YJIT 機能を含まないバイナリが作成される。

configure 時に --enable-yjit をつけておくと Rust が無い環境だとビルド時にエラーになるので気づけて良さそう。