DiffDaily

Deep & Concise - OSS変更の定点観測

[Rails] Ruby 3.3未満の互換性コードを削除

rails/rails

背景

RailsのmainブランチがRuby 3.3以上を必須とすることに伴い、古いRubyバージョンとの互換性を保つために実装されていたコードが不要になりました。この変更は、コードベースをよりシンプルに保ち、保守性を向上させることを目的としています。

削除された互換性コード

1. SecureRandomのパラメータチェック

Ruby 3.3以降では SecureRandom.alphanumeric が常に2つのパラメータ(長さと文字セット)を受け取れるようになりました。これにより、Ruby 3.2以前のための分岐処理が不要になりました。

変更前:

if SecureRandom.method(:alphanumeric).parameters.size == 2
  def self.base58(n = 16)
    alphanumeric(n, chars: BASE58_ALPHABET)
  end
else
  def self.base58(n = 16)
    SecureRandom.random_bytes(n).unpack("C*").map do |byte|
      idx = byte % 64
      idx = SecureRandom.random_number(58) if idx >= 58
      BASE58_ALPHABET[idx]
    end.join
  end
end

変更後:

def self.base58(n = 16)
  alphanumeric(n, chars: BASE58_ALPHABET)
end

この変更は base58base36base32 の3つのメソッドすべてに適用されています。Ruby 3.2以前では alphanumeric メソッドがカスタム文字セットをサポートしていなかったため、バイト配列を手動で処理する実装が必要でしたが、Ruby 3.3以降はシンプルな実装で統一できます。

2. Range#overlap?メソッド

Ruby 3.3で Range#overlap? がコアに追加されたため、Active Supportでの独自実装が削除されました。

削除されたコード:

unless Range.method_defined?(:overlap?)
  def overlap?(other)
    raise TypeError unless other.is_a? Range

    self_begin = self.begin
    other_end = other.end
    other_excl = other.exclude_end?

    return false if _empty_range?(self_begin, other_end, other_excl)

    other_begin = other.begin
    self_end = self.end
    self_excl = self.exclude_end?

    return false if _empty_range?(other_begin, self_end, self_excl)
    return true if self_begin == other_begin

    return false if _empty_range?(self_begin, self_end, self_excl)
    return false if _empty_range?(other_begin, other_end, other_excl)

    true
  end

  private
  def _empty_range?(b, e, excl)
    return false if b.nil? || e.nil?

    comp = b <=> e
    comp.nil? || comp > 0 || (comp == 0 && excl)
  end
end

Ruby 3.3以降では、Rangeクラスに標準で overlap? メソッドが実装されているため、この複雑な互換性コードは不要になりました。エイリアス overlaps? は引き続き提供されます。

3. Fiber#killメソッド

Ruby 3.3で Fiber#kill が追加されたため、テストコード内のモックメソッドが削除されました。

削除されたコード:

unless method_defined?(:kill)
  def kill
  end
end

これは、コネクションプールのテストで使用されていた擬似Fiberクラスの互換性メソッドです。Ruby 3.3以降では実際に Fiber#kill が存在するため、この定義は不要になりました。

影響範囲

この変更により、Railsの内部実装がよりシンプルになり、Ruby 3.3の新機能を直接利用できるようになりました。アプリケーション開発者への直接的な影響はありませんが、Rails 8.0以降ではRuby 3.3未満のバージョンでは動作しなくなります。