Help us understand the problem. What is going on with this article?

num && num > 0はダサい

More than 1 year has passed since last update.

結論

numがnilを懸念して
num && num > 0 をするなら
num &.> 0の方が良い。
(&.を知らない方はおまけをご参照ください)
(ちなみに他に&&で条件を結ぶ場合は結合順が変わってしまう可能性があるので注意ください)

Ruby: ぼっち演算子&.の落とし穴(翻訳)
https://techracho.bpsinc.jp/hachi8833/2017_11_21/48340

なんで?

>もメソッドだから、&.を使ってnil.>(0)となってしまう場合のNoMethodErrorを避けられるじゃん。

結論は本当か

num && num > 0num &.> 0は同値?

→ 答えはNOです

num = 1
num && num > 0 #=> true
num &.> 0 #=> true

num = 0
num && num > 0 #=> false
num &.> 0 #=> false

num = nil
num && num > 0 #=> nil
num &.> 0 #=> nil

num = false
num && num > 0 #=> false
num &.> 0 #NoMethodError (undefined method `>' for false:FalseClass)

object&.some_methodは、objectがnilのときにnilを返し、
そうでないときにsome_methodを呼ぶので、numが偽だけどnilじゃないケースで両者に差が出ます。
num = false のときに、&.では>というメソッドを呼び出すのでエラーになってしまいます。

結論は本当か?

numがnilを懸念して  と書きましたので本当だと思います。
ただ前述のようにnumが偽だけどnilじゃない → num=false の場合には異なる出力になります。
  
  

以下おまけ( &.と .try と <)

&.とは?

  • safe navigation operator (ぼっち演算子):
    • object&.foo という形式のメソッド呼び出し形式が追加されました。これは object が nil でないときにメソッド foo を呼び出します。 Active Support の try! と似ていますが、メソッド名は文法的に必須であるという点が異なります。

リファレンスより引用

.tryとは?

Active Supportによってサポートされているメソッドです。
object.try(:method_name)のように使います。
これを使うと今回の話のやつは num.try(:>,0) と書けます。

tryメソッドは、NoMethodErrorを握りつぶして代わりにnilを返す点に注意が必要です。

https://railsguides.jp/active_support_core_extensions.html#try

&.を基準にすると、.tryはobjectがnilではないがmethod_nameというメソッドが存在しないケースでNoMethodErrorではなくnilを返すので、&.よりもErrorが起きにくいメソッドと言えると思います。

method_nameがあればエラーは起きないか?

当然ながら、そんな訳無いですね。
num = 'somestring' の場合num.try(:>,0) は ArgumentErrorを返します。
メソッド>はStringにもあるが、StringとIntegerを>で比較しようとして怒られている状態です。
Stringでの>はString同士の辞書順の大小関係の比較、
Integerの>は数値の大小比較。
違うクラスのものを比較できる訳がないってことですね!

でもIntegerとFloatは普通に比較できるじゃん

FloatとIntegerが比較できるのは Numeric#coerce のおかげ
StringはNumericクラスを継承していないから比較できないみたいです。
https://docs.ruby-lang.org/ja/latest/method/Numeric/i/coerce.html

そもそもなんでこんな話を?

以前
some.try(:something_to_count) && some.try(:something_to_count) > 0
というコードを見かけました。
some.try(:something_to_count)&.> 0
って書いたら良いのになあと思いましたが、めんどくさくてやめたのを思い出して、
めんどくさいながらも記事を書きました。

引用集

Ruby: ぼっち演算子&.の落とし穴(翻訳)
https://techracho.bpsinc.jp/hachi8833/2017_11_21/48340
ぼっち演算子のリファレンス
https://docs.ruby-lang.org/ja/latest/doc/news=2f2_3_0.html
Railsガイドのtryの情報
https://railsguides.jp/active_support_core_extensions.html#try
Numeric#coerce の話
https://docs.ruby-lang.org/ja/latest/method/Numeric/i/coerce.html

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away