Template クラスにフォーマット検証・正規化ヘルパーを抽出
この PR は Template::Types への直接依存を排除し、フォーマットのバリデーションと正規化ロジックを Template クラスに移譲すると同時に、autoload の重複と順序を整理しました。結果として、Action Dispatch がロードされているか否かに関わらず同一のインターフェースで利用でき、コードベースの可読性が向上します。
背景
Template::Types は Action Dispatch がロードされている環境では別実装になるため、LookupContext から直接呼び出すと環境依存の振る舞いが発生していました。そのため、フォーマット検証ロジックを Template に切り出すことで、実装差異を隠蔽し一元管理する必要がありました。また、eager_autoload ブロック内で同一クラスが二度 autoload されている箇所があり、将来的なメンテナンスでミスが起きやすい状態でした。
技術的な変更
Template クラスに validate_formats と normalized_formats の二つのクラスメソッドが追加されました。validate_formats は渡された配列が Types.symbols に含まれるか検証し、違反があれば ArgumentError を送出します。normalized_formats は有効なシンボルだけを抽出し、無効な場合は nil を返すシンプルな正規化ユーティリティです。
class Template
class << self
def validate_formats(formats)
return if Types.valid_symbols?(formats)
invalid = formats - Types.symbols
raise ArgumentError, "Invalid formats: #{invalid.map(&:inspect).join(", ")}"
end
def normalized_formats(formats)
formats & Types.symbols unless Types.valid_symbols?(formats)
end
end
end
LookupContext の実装が二か所で更新されています。DetailsKey.details_cache_key では、従来 Template::Types.valid_symbols? を呼び出していた箇所を Template.normalized_formats に置き換え、正規化されたフォーマット配列をキャッシュキーに使用するようにしました。また、LookupContext#formats= では、手動でシンボル検証とエラーメッセージ生成を行っていたロジックを Template.validate_formats に委譲しています。
# 変更前
unless Template::Types.valid_symbols?(values)
invalid_values = values - Template::Types.symbols
raise ArgumentError, "Invalid formats: #{invalid_values.map(&:inspect).join(", ")}"
end
# 変更後
Template.validate_formats(values)
# 変更前
if formats = details[:formats]
unless Template::Types.valid_symbols?(formats)
details[:formats] &= Template::Types.symbols
end
end
# 変更後
if normalized = Template.normalized_formats(formats)
details[:formats] = normalized
end
Template の autoload 順序が整理され、重複していた autoload :Types エントリが削除されました。さらに、RawFile、Renderable、Handlers などのロード順がアルファベット順に揃えられ、将来的な追加や削除が視認しやすくなります。
@@
- autoload :RawFile
- autoload :Renderable
- autoload :Handlers
+ autoload :HTML
+ autoload :Handlers
+ autoload :Inline
+ autoload :RawFile
+ autoload :Renderable
autoload :Sources
autoload :Text
- autoload :Types
+ autoload :Types
設計判断
Template へロジックを移行した最大の意図は、外部からの呼び出し側が Template::Types の実装詳細を意識せずに済むようにすることです。validate_formats と normalized_formats は内部で Types のメソッドを利用していますが、公開インターフェースは Template のみで統一され、既存コードは Template.validate_formats へ置換えるだけで機能が保たれます。autoloader の整理は、名前空間のロード順序を一貫させることで、将来的なリファクタリング時のヒューマンエラーを防止する設計選択と言えます。
まとめ
本 PR はフォーマット処理を Template に集約し、環境依存を排除すると同時に autoload の重複・順序問題を解消しました。公開 API の変更はなく、既存の呼び出し側は同等の振る舞いを維持しつつ、コードの意図が明確になるという副次的効果も得られています。