Ractor の shareability メソッドを Ruby 4.0 以降でのみ有効化

rails/rails

Ruby 3 系で Ractor.shareable_proc が未実装であることに起因する例外を防止するため、Rails は Ractor 関連ヘルパーを Ruby 4.0 以降でのみ有効にし、互換性のない環境では no‑op に置き換えます。

背景

Ractor.shareable_proc が Ruby 3.x に存在しないため、Rails の内部ヘルパーが呼び出すと NoMethodError が発生するリスクがあります。具体的には proc = ractor_shareable_proc { foo } として取得したプロックを ractor_make_shareable(Bar.new(proc)) に渡すと、Ruby 3.4 では例外がスローされます。これは make_shareable が未共有可能なプロックを受け取っても安全に動作しない という根本的な不整合です。

技術的な変更

この PR では activesupport/lib/active_support/ractors.rb に単一のバージョン判定を導入し、Ruby 4.0 以上でのみ本来の Ractor メソッドを呼び出す実装に切り替えました。条件分岐がシンプルになることで、コードベース全体に散在していたバージョンチェックが集中します。

変更前:

module ActiveSupport
  module Ractors
    class << self
      if defined?(Ractor) && Ractor.respond_to?(:make_shareable)
        def make_shareable(...)
          Ractor.make_shareable(...)
        end
      else
        def make_shareable(obj, copy: false)
          obj
        end
      end
      # shareable?, shareable_proc, shareable_lambda も同様の分岐
    end
  end
end

変更後:

module ActiveSupport
  module Ractors
    class << self
      if defined?(Ractor) && RUBY_VERSION >= "4.0"
        def make_shareable(...)
          Ractor.make_shareable(...)
        end

        def shareable?(obj)
          Ractor.shareable?(obj)
        end

        def shareable_proc(...)
          Ractor.shareable_proc(...)
        end

        def shareable_lambda(...)
          Ractor.shareable_lambda(...)
        end
      else
        def make_shareable(obj, copy: false)
          obj
        end

        def shareable?(obj)
          obj
        end

        def shareable_proc(self: nil, &block)
          block
        end

        def shareable_lambda(self: nil, &block)
          block
        end
      end
    end
  end
end

Ruby 4.0 以上では Ractor.make_shareable などがそのまま呼び出され、Ruby 3.x ではすべてのヘルパーが引数をそのまま返す安全なスタブとなります。これにより、未実装メソッドへの呼び出しが原因で発生していた例外は完全に回避されます。

設計判断

バージョン依存ロジックを一箇所に集約し、Rails コア全体で散在していた個別チェックを排除した点が本変更の主たる設計方針です。ActiveSupport::Ractors 名前空間に閉じることで、Kernel への公開 API 追加による潜在的な衝突を回避し、将来的に Ruby 4.0 への移行が完了した際のクリーンアップも容易になります。

no‑op 実装は 後方互換性を担保しつつ、Ruby 3.x 環境での動作を安全に保ちます。これにより、Rails アプリケーションは Ruby のバージョンに応じて自動的に適切な挙動を選択でき、追加のバージョンチェックコードを書き加える必要がなくなります。

まとめ

本 PR は Ractor の shareability ヘルパーを Ruby 4.0 以降でのみ有効化し、Ruby 3.x では安全な no‑op に置き換えることで、未実装メソッド呼び出しによる例外を根本的に排除しました。バージョン判定を ActiveSupport::Ractors に集中させた設計により、コードの可読性と保守性が向上しています。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
5daaeefd

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文・背景・技術的な変更・設計判断・まとめの5セクションが揃っており、総論→各論→結論の流れが明確です。必須要素はすべて含まれています。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは正しい `ruby:ファイルパス` 形式で記述されています。GitHubリンクは PR 番号が `[#57550]` ではなく `PR #57550` と記載されており、仕様の `[#123](URL)` 形式から外れていますが、可読性への影響は小さいです。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

内容は Rails/ActiveSupport の内部実装に関する専門的な説明で、エンジニア向けに適切です。初心者向けの余計な説明はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは冒頭に要点を示す総論パラグラフがあり、続く段落で具体例やコードを示し、最後にまとめる構成が取られています。段落は1文がトピックセンテンスで始まり、1段落1トピック、長さも6文未満で空行で区切られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内の「変更前」・「変更後」コードは提供されたDiffと一致しています。ファイル名・構文も正しく示されており、Diffの内容が正確に反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

Ractor、shareable_proc、make_shareable などの用語は PR の記述と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的な主張(例外回避、バージョン判定の集中化)は PR の目的と完全に合致しており、根拠が明示されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

全ての事実(Ruby 4.0 以降で有効化、no‑op の挙動など)は PR の背景・目的と合致し、捏造や推測はありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR 番号 #57550、Ruby バージョン 3.x・4.0 などの数値は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR タイトルの意味を日本語で正確に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

LTS やリリース日程など、PR に記載されていない外部情報は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現は使用されておらず、PR の記述と齟齬はありません。