はじめに
こちらの記事はRails 7.0.7 バージョンアップ対応の第2弾です。
今回はActiveSupport
のto_s
に関した変更1について確認していきます。
なお、前回記事はこちらとなります。
まとめ
デフォルトのフォーマットを指定しても、引数なしのto_s
だと反映されないバグがありました。
v7.0.7では、引数なしto_s
でもデフォルトのフォーマットが反映されるようになります。
デフォルトのフォーマットを利用している場合は、引数なしのto_s
において反映されているか確認してください。
されていないときは、to_s
をto_fs
に修正してください。
経緯
Railsでは、いくつかのRuby組み込みクラスが拡張されています。例えば、Object
クラスにはblank?
が追加されています。これらの拡張部分はActiveSupport
のcore_ext
2にまとめられています。
今回のバージョンアップで対象となっているのは、Time
クラスなどで拡張されているto_s
となります。
上記のto_s
はフォーマットを指定できるような拡張が施されていました。
このような拡張がされている一方で、Rubyの組み込みのto_s
のパフォーマンスがv3.1で改善されました3。Railsでも、その恩恵を享受したいところですが、上記の拡張が施されており叶いませんでした。
そこで、Rails v7からは、拡張のto_s
をto_formatted_s
(to_fs
)に名称を変更することで、組み込みの部分と拡張部分のどちらも利用できるようになっています[^5]。
問題点
上記のto_s
からto_fs
の変更に当たって、既定のフォーマットを利用したものでデグレが発生しています。
ですが、Time::DATE_FORMATS[:default] = "%Y/%m/%d"
のように既定のフォーマットを指定したとき、v6では引数なしのto_s
でもフォーマットが適応されていたところを、v7ではフォーマットが適応されませんでした。
これは、v7では、引数なしのto_s
はRubyの組み込みのto_s
が呼ばれるようになったためです。
なお、フォーマットの引数あり(to_s(:format)
)で利用していた場合は、問題なくフォーマットが適応されます。
バージョンアップに伴う変更点
デフォルトのフォーマットが設定されている場合は、引数なしto_s
でもデフォルトフォーマットが適応されるようになりました。
動作確認
Time
を参考にして動作確認します。また、to_s
に加えてto_fs
も確認します。
なお、動作確認ようのコードはGithubで公開しております4。
フォーマットなし
フォーマットなしで実行するとto_s
、to_fs
ともに同じ文字列を出力します。
time = Time.new(2000,1,1,11,0,0)
puts "without default format"
puts "Time#to_s: " + time.to_s
puts "Time#to_fs: " + time.to_fs
without default format
Time#to_s: 2000-01-01 11:00:00 +0900
Time#to_fs: 2000-01-01 11:00:00 +0900
フォーマットあり
デフォルトのフォーマットを指定すると、v7.0.6ではフォーマットが反映されません。
puts "with default format"
Time::DATE_FORMATS[:default] = "%Y年%m月%d日 %H時%M分%S秒"
puts "Time#to_s: " + time.to_s
puts "Time#to_fs: " + time.to_fs
with default format
Time#to_s: 2000-01-01 11:00:00 +0900
Time#to_fs: 2000年01月01日 11時00分00秒
with default format
Time#to_s: 2000年01月01日 11時00分00秒
Time#to_fs: 2000年01月01日 11時00分00秒
一方で,to_s(:default)
のように引数ありでデフォルトフォーマットを指定すれば、v7.0.6のto_s
でもフォーマットが適応されます。
puts "Time#to_s(:default): " + time.to_s(:default)
Time#to_s(:default): 2000年01月01日 11時00分00秒