Ruby: 数値のゼロチェックには'== 0'よりも'zero?'メソッドを使おう(翻訳)
Rubyの構文や標準ライブラリが提供するメソッドは、他の言語に比べて読みやすさ(と喜び)をしばしば優先しています。
その例の1つは、値をゼロと比較するときのシンタックスシュガーです。
それぞれのドキュメントのzero?
メソッドの項を読んでみてください。
🔗 以下のように書くよりも
値が0
に等しいかどうかのチェックを条件に書く。
if number == 0
:yes
else
:no
end
🔗 以下のように書こう
すべての数値型に組み込まれている#zero?
メソッドを使う。
if number.zero?
:yes
else
:no
end
🔗 そうする理由
Rubyらしい書き方にすることで意味も明確になり、間違いが起こりにくくなります。
1番目のサンプルコードでは、うっかりnumber = 0
と書いてしまう凡ミスが非常に起きやすくなります。こう書いてしまうと、変数との比較ではなく変数への代入が実行されてしまいます(この種のエラーから保護するためにテストを書いてもいいのですが)。
🔗 そうしない理由があるとすれば
== 0
構文を採用している類似の言語はとても多く、広く知れ渡っています。Rubyプログラミング歴15年の私も、未だに上述のアドバイスの適用に苦労しています。
「パフォーマンス」を理由としてこの書き方に反発する人も一部にいるでしょう。
require "benchmark/ips"
Benchmark.ips do |x|
x.report("1 == 0") { 1 == 0 } #=> false
x.report("0 == 0") { 0 == 0 } #=> true
x.report("1.zero?") { 1.zero? } #=> false
x.report("0.zero?") { 0.zero? } #=> true
x.report("1.0 == 0") { 1.0 == 0 } #=> false
x.report("0.0 == 0") { 0.0 == 0 } #=> true
x.report("1.0.zero?") { 1.0.zero? } #=> false
x.report("0.0.zero?") { 0.0.zero? } #=> true
end
Integer
の場合:
1 == 0
- 29.049M (± 0.7%) i/s
0 == 0
- 28.972M (± 0.3%) i/s
1.zero?
- 23.009M (± 1.0%) i/s
0.zero?
- 22.860M (± 1.7%) i/s
Float
の場合:
1.0 == 0
- 18.768M (± 2.0%) i/s
0.0 == 0
- 19.066M (± 0.5%) i/s
1.0.zero?
- 22.784M (± 0.6%) i/s
0.0.zero?
- 22.841M (± 0.8%) i/s
このベンチマークでは、Integer
は==
構文の方が高速ですが、Float
では.zero?
の方が勝っています2。
しかし重要なのは、どちらも1秒間に数千万回実行される点では同じということです。自分のコードではパフォーマンスへの影響を気にするより読みやすさを重視しましょう。
概要
元サイトの許諾を得て翻訳・公開いたします。
日本語タイトルは内容に即したものにしました。