`number_to_human` と `number_to_human_size` の `precision: nil` クラッシュを修正
precision: nil が指定されたときに number_to_human と number_to_human_size が例外を投げていた問題を、比較前に precision の有無を確認するガードを追加して解消しました。
背景
precision: nil は他の数値ヘルパー(number_to_currency など)で正式にサポートされており、オプションとして受け入れられテストも通っていますが、number_to_human 系はデフォルトで significant: true を設定し、内部で RoundingHelper#absolute_precision を経由していました。
そのメソッド内で options[:precision] > 0 と直接比較していたため、precision が nil の場合に NoMethodError: undefined method '>' for nil が発生し、呼び出し側がクラッシュしていました。
この挙動は特に number_to_human(123456, precision: nil) や number_to_human_size(123456, precision: nil) で顕在化し、既存のテストではカバーされていなかったため修正が必要となりました。
技術的な変更
RoundingHelper#absolute_precision に対し、options[:precision] が真であることを確認する guard 条件を追加しました。これにより precision が nil の場合は比較がスキップされ、options[:precision] のデフォルト動作が保持されます。
@@
- if options[:significant] && options[:precision] > 0
+ if options[:significant] && options[:precision] && options[:precision] > 0
options[:precision] - digit_count(convert_to_decimal(number))
else
options[:precision]
テストスイートにも precision: nil のケースが追加され、number_to_human_size(123456, precision: nil) が期待通り "120.5625 KB" を、number_to_human(123456, precision: nil) が "123.456 Thousand" を返すことが確認されています。
@@
+ assert_equal "120.5625 KB", number_helper.number_to_human_size(123456, precision: nil)
@@
+ assert_equal "123.456 Thousand", number_helper.number_to_human(123456, precision: nil)
設計判断
この修正は NumberToRoundedConverter#convert で採用されていたパターン if precision = options[:precision] → precision > 0 と同等の安全なガードを RoundingHelper に導入したことを意味します。
ガードを追加するだけのシンプルな変更であるため、既存の precision が数値で指定されたケースへの振る舞いは一切変わらず、後方互換性が確保されています。
また、コードベース全体で options[:precision] の有無を明示的にチェックする統一性が高まり、将来的な拡張やバグ修正時の認識コストが低減します。
まとめ
precision: nil が許容される他ヘルパーと同様に、number_to_human 系でも安全にオプションを受け取れるようガードを追加したことで例外が解消され、テストでの検証も完了しました。既存機能への影響はなく、コードの一貫性が向上した変更です。