Simplify PRE_CONTENT_STRING hash

rails/rails

Rails 7 removes the default empty‑string proc from PRE_CONTENT_STRINGS and relies on Ruby 3.1’s optimisation that "#{nil}" no longer allocates a new String. The change shortens the constant definition while preserving the existing tag‑rendering behaviour.

背景

PRE_CONTENT_STRINGS was built with a shareable proc that returned a frozen empty string to avoid object allocations when interpolating nil values in content_tag_string. This defensive default was introduced because, prior to Ruby 3.1, the expression "#{nil}" created a fresh empty String, inflating per‑request allocations.

The framework needed the proc to keep memory usage low while remaining Ractor‑safe, so the hash was created via Hash.new(&ActiveSupport::Ractors.shareable_proc { "" }) and then frozen.

Since Ruby 3.1 optimises nil interpolation to reuse the empty string literal, the explicit default value no longer provides a memory benefit, allowing it to be dropped without functional impact.

技術的な変更

The constant is now defined as a literal frozen hash, eliminating the shareable‑proc indirection.

@@ -41,10 +41,10 @@ module TagHelper
       TAG_TYPES.merge! CLASS_PREFIXES.index_with(:class)
       TAG_TYPES.freeze

-      PRE_CONTENT_STRINGS             = Hash.new(&ActiveSupport::Ractors.shareable_proc { "" })
-      PRE_CONTENT_STRINGS[:textarea]  = "\n"
-      PRE_CONTENT_STRINGS["textarea"] = "\n"
-      PRE_CONTENT_STRINGS.freeze
+      PRE_CONTENT_STRINGS = {
+        textarea: "\n",
+        "textarea" => "\n",
+      }.freeze

       # = Action View Tag Builder
       #

When an unknown key is looked up, the hash now returns nil; the surrounding interpolation "#{PRE_CONTENT_STRINGS[name]}" yields an empty string automatically because Ruby 3.1 does not allocate a new String for nil.

The PR’s IRB benchmark confirms the behaviour: after the first call, both "#{a}" (where a is a frozen empty string) and "#{nil}" allocate only a single object, showing no regression after the default is removed.

Thus the modification simplifies the source while keeping tag rendering identical to the previous implementation.

設計判断

The refactor favours simplicity by discarding a custom proc that is now redundant, letting the language runtime handle the edge case. This reduces indirection and the amount of code that must be kept Ractor‑compatible.

Because the hash is still frozen, it remains shareable across Ractors, and the only keys used by the framework (:textarea and "textarea") are explicitly defined, so behaviour for all supported tags is unchanged.

The design choice lowers maintenance overhead and aligns Rails with modern Ruby semantics without sacrificing safety or performance.

まとめ

By removing an obsolete default‑value proc from PRE_CONTENT_STRINGS, Rails leverages Ruby 3.1’s nil‑interpolation optimisation, resulting in a cleaner, Ractor‑safe constant definition while keeping the rendered output unchanged.

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
6517f0fa

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文が2文で要旨を示し、背景・技術的変更・設計判断・まとめの各セクションが揃っている。全体が総論→各論→結論の流れになっている。

カスタムMarkdown構文 ✓ PASS

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

コードブロックは正しいdiffハイライト形式。GitHubリンクはPR番号が#付きで正しくリンク化されている。シンタックスハイライトのエラーはなし。

対象読者への適合性 ✓ PASS

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

Railsエンジニア向けに技術的詳細が中心で、初心者向けの過度な説明はない。

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

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

各セクションが総論・各論・結論の段落構成になり、段落はトピックセンテンスで始まり1段落1トピック、6文以下で区切られている。

Diff内容との照合 ✓ PASS

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

記事内のdiffブロックは提供されたDiffと完全に一致し、ファイル名・変更箇所が正確に反映されている。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

PRE_CONTENT_STRINGS、shareable_proc、Ractors、freeze などの用語がPRと一致し、誤用はない。

説明の技術的正確性 ✓ PASS

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

Ruby 3.1 の nil 補間最適化による効果、メモリ割当削減がなくなる点、動作上の影響がないことが正確に説明されている。

事実の突合 ✓ PASS

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

全ての主張がPRのタイトル・説明・Diffで裏付けられている。ベンチマーク結果や動作保証に関する記述はPRに含まれる情報と合致している。

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

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

PR番号 #57760 が正しく記載されている。その他数値や固有名詞の誤りはない。

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

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

記事タイトルはPRタイトルと完全に一致している。

外部知識の正確性 ✓ PASS

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

外部知識(LTS、EOL、リリース日程等)の記載はなく、PR情報のみで構成されている。

時間表現の正確性 ✓ PASS

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

時間表現の歪曲はなく、PRの記述と一致している。