結論
I18n.localize
がオススメ
理由
- 日時表示専用のメソッドだから(= スコープが小さく、オーバーライドしやすいから )
strftimeがダメな理由
undefined method strftime for nil:NilClass
エラーを回避するために無闇に&
をつけるから- 日時を表示するのに長ったらしいメソッド名・時刻フォーマットを書くのはめんどくさいから
to_s(:Time::DATE_FORMATS)がダメな理由
- スコープが広く、オーバーライドできない(すべきでない)から
to_s
にnil
を渡すと空文字を返す。
$ nil.to_s
=> ""
しかし、to_s(:Time::DATE_FORMATS)
にするとArgumentError
が発生する。
$ Time::DATE_FORMATS[:sample_format] = "%Y年%m月%d日"
=> "%Y年%m月%d日"
$ Time.now.to_s(:sample_format)
=> "2021年01月01日"
$ nil.to_s(:sample_format)
=> ArgumentError: wrong number of arguments (given 1, expected 0)
to_s
で時刻フォーマットを指定できるが、nil
を渡してもエラーを吐かないto_s
の使いやすさがなくなった。
to_s
に&
を毎回書くのは美しくないし、strftime
とやってる事が変わらなくなる。
I18n.localize
もnil
が渡るとエラーが起きる。
ja:
time:
formats:
default: "%Y年%m月%d日"
$ I18n.l(Time.now)
=> "2021年01月01日"
$ I18n.l(nil)
=> I18n::ArgumentError: Object must be a Date, DateTime or Time object. nil given.
なので
- 諦めて永遠と
&
を使い続ける(論外) -
begin rescue
でエラーをキャッチする(論外) - オーバーライドして
nil
をパスさせるか
どれかの対応が必要になる。
1は論外。美しくない。
2も論外。毎回begin resucue
するのはダルい。美しくない。
必然的に3で対応することになるが、to_s
は影響範囲が広く懸念が大きい。
なので、日時表示専用メソッドでスコープが小さく影響範囲が狭いI18n.localize
をオーバーライドするのがオススメ
オーバーライドの方法は、以下を参考にしてほしい。
http://hamasyou.com/blog/2014/02/19/rails-i18n-localize/
この記事を書こうと思った経緯と所感
I18n.localize
が日時表示用のメソッドならば、これ使えばいいんじゃね?」
って思ってました。
しかし、デフォルトではnil
をパスできないと知って、他のメソッドを調べました。
その際に、to_s
メソッドの引数に時刻フォーマットを設定すれば日時を表示できると知りました(to_sメソッド万能スギィィ!!!)
しかし、
to_s
でフォーマットを指定できるが、nil
を渡してもエラーを吐かないto_s
の使いやすさがなくなりました。。。
&
でエラー回避できますが、strftimeとやってることは変わらないし、コードが美しくないと思いました。
このように、コードの保守性とメソッドスコープの観点からI18n.localize
をオーバーライドするのがベストだと考えました。