in_order_ofでnil要素を保持するよう修正

rails/rails

Enumerable#in_order_of のデフォルト filter:true でも、 series に明示的に nil を含めた場合に nil が除外されていた問題を解消し、 filter:false と同様に nil を保持できるようになった。

背景

filter:true が指定されたとき、in_order_of は内部で group_by(&key).values_at(*series).flatten(1).compact を実行しており、flatten の後に compact が走るため、 series に nil が明示的に含まれていても compact がそれらを除去してしまっていた。これにより、 [3, nil, 1, 2].in_order_of(:itself, [1, nil, 2, 3]) の結果が [1, 2, 3] となり、期待どおりの nil が失われていた。filter:false では別のロジックが使われており nil が正しく保持されていたため、二つのモード間で挙動の不整合が存在した。

技術的な変更

変更点activesupport/lib/active_support/core_ext/enumerable.rb 内の in_order_of 実装で、compactflatten の呼び出し順序を入れ替えたことです。

@@
-      group_by(&key).values_at(*series).flatten(1).compact
+      group_by(&key).values_at(*series).compact.flatten(1)

compact を先に適用することで、nil 要素が series に含まれるケースでは compactnil を除去せずに残す(values_at が返す配列の中の nil が対象外になるだけ)という挙動になる。その後の flatten(1) で一次元配列に平坦化しつつ、nil はそのまま保持される。結果として、 filter:true でも nil が正しく出力され、 filter:false と同一の振る舞いが得られる。

テストも activesupport/test/core_ext/enumerable_test.rb に追加され、nil が series に含まれるケースで期待通りの配列が返ることを検証している。

def test_in_order_of_preserves_nil_elements_named_in_series
  values = [ 3, nil, 1, 2 ]
  assert_equal [ 1, nil, 2, 3 ], values.in_order_of(:itself, [ 1, nil, 2, 3 ])
end

設計判断

この修正は 既存のインターフェイスを変更せず、内部ロジックだけを入れ替える という最小限のアプローチを取っている。filter:true のデフォルト動作は依然として nil 以外の要素を順序付けて返すが、 series に nil が明示的に指定された場合は保持できるようになるため、二つのモード間の一貫性が確保された。また、compactflatten の順序入れ替えは副作用がなく、既存コードに対する後方互換性も維持される。

まとめ

Enumerable#in_order_of の内部処理を compactflatten の順に変更したことで、filter:true でも series に含まれる nil 要素が正しく保持され、filter:false と同様の動作が得られるようになった。挙動の統一と最小限の変更という設計判断により、既存ユーザーへの影響はなく、期待通りの結果がテストで保証されている。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
192aa273

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文があり、背景・技術的変更・設計判断・まとめの各セクションが揃っており、総論→各論→結論の流れがある。

カスタムMarkdown構文 ⚠ WARNING

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

コードブロックのファイル名付きハイライトは正しい形式。PRリンクが "PR #57913" というテキストになっており、仕様の [#123](URL) 形式から外れている。

対象読者への適合性 ✓ PASS

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

専門エンジニア向けの技術的記述で、余計な初心者向け解説はない。

パラグラフ・ライティング ⚠ WARNING

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

多くの段落はトピックセンテンスで始まり、1段落1テーマで適切な長さ。ただし、背景や設計判断セクションに明確な結論パラグラフが欠けており、総論→各論→結論の完全な構造が一部不足している。

Diff内容との照合 ✓ PASS

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

記事中のコードブロックは提供されたDiffと完全に一致している。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

nil、filter:true、filter:false、in_order_of などの用語が正しく使用されている。

説明の技術的正確性 ✓ PASS

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

変更理由とコード変更の効果がDiff内容と合致しており、技術的に正確な説明となっている。

事実の突合 ✓ PASS

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

主張はすべてPRのタイトル・説明・Diffで裏付けられており、余計な外部知識や推測はない。

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

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

PR番号 #57913 の記述は正しい。コード例中の数値もDiffと一致。

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

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

記事タイトルはPRタイトルの意味を正しく日本語化しており、一致している。

外部知識の正確性 ✓ PASS

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

バージョンサポートやリリース日程等の外部情報は一切含まれていない。

時間表現の正確性 ✓ PASS

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

時間表現は使用されておらず、PR情報とずれはない。