Mime::SET、Mime::LOOKUP、Mime::EXTENSION_LOOKUP の非推奨化と新 API の導入
この PR は、内部レジストリへの直接参照を提供していた Mime::SET、Mime::LOOKUP、Mime::EXTENSION_LOOKUP を ActiveSupport::Deprecation::DeprecatedObjectProxy でラップし、使用時に警告を出す形で非推奨化します。同時に Mime.extensions メソッドを追加し、公開 API だけで同等の機能が利用できるようにします。
背景
Mime モジュールの定数が内部レジストリオブジェクトをそのまま公開していたため、外部からミュータブルな状態が参照可能でした。 その結果、予期しない変更が伝搬するリスクが指摘され、Rails のカプセル化方針に合致しない点が問題視されました。PR の説明では、同等の操作はすでに Mime.symbols や Mime::Type.lookup 系の公開 API で提供されていることが示されています。したがって、定数自体を削除せずに警告付きで非推奨化し、利用者を安全な API へ誘導する方針が採られました。
技術的な変更
Mime::SET、Mime::LOOKUP、Mime::EXTENSION_LOOKUP が DeprecatedObjectProxy に置き換えられ、参照時にデプリケーション警告が出力されます。 ラップされたオブジェクトはそれぞれ内部レジストリ @registry、@lookup_by_string、@lookup_by_extension を保持し、既存コードは動作を継続しつつ警告を受け取ります。
@@
- SET = Mimes.new
- EXTENSION_LOOKUP = {} # rubocop:disable Style/MutableConstant
- LOOKUP = {} # rubocop:disable Style/MutableConstant
+ @registry = Mimes.new
+ @lookup_by_string = {}
+ @lookup_by_extension = {}
+
+ SET = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
+ @registry,
+ "Mime::SET is deprecated. Use Mime.symbols to enumerate registered types, or Mime[...] / Mime::Type.lookup to look one up.",
+ ActionDispatch.deprecator,
+ )
+ LOOKUP = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
+ @lookup_by_string,
+ "Mime::LOOKUP is deprecated. Use Mime::Type.lookup instead.",
+ ActionDispatch.deprecator,
+ )
+ EXTENSION_LOOKUP = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
+ @lookup_by_extension,
+ "Mime::EXTENSION_LOOKUP is deprecated. Use Mime.extensions to enumerate registered extensions, or Mime::Type.lookup_by_extension / Mime[...] to look one up.",
+ ActionDispatch.deprecator,
+ )
Mime.extensions メソッドが追加され、登録された全拡張子(エイリアスを含む)を列挙できるようになりました。 これにより、旧来の Mime::EXTENSION_LOOKUP.map(&:first) と同等の情報取得が Mime.extensions で行えます。テストコードでも新メソッドへの呼び替えが確認されています。
@@
- def symbols
- SET.symbols
+ def symbols
+ @registry.symbols
+ end
+
+ def extensions
+ @lookup_by_extension.keys
end
定数参照を直接行っていたコードパスが Mime.symbols や Mime::Type.lookup 系へ置き換えられました。 変更対象には actionmailer/lib/action_mailer.rb、actionpack/lib/action_dispatch.rb、actionpack/lib/abstract_controller/collector.rb などが含まれ、テストコードでも期待値が新 API に合わせて更新されています。置換後のコードは機能的に等価であり、動作に差分はありません。
@@
- ActionView::Base.default_formats ||= Mime::SET.symbols
+ ActionView::Base.default_formats ||= Mime.symbols
設計判断
非推奨化の手段として定数を削除せず DeprecatedObjectProxy でラップする方針が採用されました。 この選択により、即時のブレーク変更を回避しつつ、開発者に対してデプリケーション警告で移行タイミングを示すことが可能です。代替案として新しい定数キーの追加が議論されましたが、API の肥大化を防ぐ観点から既存キーのラップが最小侵入で実装できました。
新しい公開メソッド Mime.extensions と既存の Mime.symbols、Mime::Type.lookup 系の組み合わせで、旧定数が提供していたすべての機能をカバーします。 Mime.extensions はエイリアスを含む全拡張子を返すため、Mime::EXTENSION_LOOKUP が担っていた列挙機能を完全に代替します。結果として、内部レジストリへの直接触査が排除され、API が一元化されました。
まとめ
この変更は、 Mime の内部状態への直接露出を排除し、 Mime.symbols、Mime::Type.lookup、Mime.extensions の公開 API に集約することで、既存コードの互換性を保ちつつ安全な利用方法を提示します。非推奨化は警告を通じて段階的な移行を促す設計となっています。