`Date::DATE_FORMATS` の意図しない `freeze` を取り消す修正
Date::DATE_FORMATS に誤って適用されていた .freeze を除去し、ユーザーがカスタムフォーマットを追加できる本来の仕様を回復しました。
背景
Date::DATE_FORMATS は、ユーザーが独自のフォーマットを追加することを想定した拡張ポイントです。定数自体のコメントにも DATE_FORMATS[:month_and_year] = "%B %Y" のような追加方法が明記されており、ミュータブルであることが前提の設計となっています。
しかし、コミット 34bce3f において .freeze が意図せず付与され、カスタムフォーマットの追加時に FrozenError が発生する状態になっていました。本PRはこの意図しない変更を取り消すものです。
技術的な変更
activesupport/lib/active_support/core_ext/date/conversions.rb から .freeze を除去し、RuboCopの Style/MutableConstant 警告を抑制するコメントを追加しました。
変更前:
DATE_FORMATS = {
short: "%d %b",
long: "%B %d, %Y",
...
iso8601: lambda { |date| date.iso8601 }
}.freeze
変更後:
DATE_FORMATS = { # rubocop:disable Style/MutableConstant
short: "%d %b",
long: "%B %d, %Y",
...
iso8601: lambda { |date| date.iso8601 }
}
このアプローチは、activesupport/lib/active_support/core_ext/time/conversions.rb の Time::DATE_FORMATS で既に採用されているパターンと統一されています。
設計判断
意図的にミュータブルな定数として維持する という判断が取られました。
RuboCopの Style/MutableConstant ルールは通常、定数の意図しない変更を防ぐために .freeze を推奨しますが、DATE_FORMATS はその例外にあたります。フォーマットの追加・上書きをユーザーに開放することがAPIの契約であるため、rubocop:disable コメントで明示的に例外として扱っています。同様の設計は Time::DATE_FORMATS にも適用されており、両定数の一貫性も回復しています。
まとめ
本PRは .freeze の一行削除と rubocop:disable コメントの追加という最小限の変更で、Date::DATE_FORMATS の拡張性を本来の仕様に戻しています。Time::DATE_FORMATS との一貫性も回復し、カスタムフォーマットを追加しているアプリケーションで発生していた FrozenError が解消されます。