値がゼロかゼロかを確認するための簡潔な方法を探しています。現在、私は次のようなことをしています。
if (!val || val == 0)
# Is nil or zero
end
しかし、これは非常に不器用なようです。
回答:
オブジェクトにはnilがありますか?メソッド。
if val.nil? || val == 0
[do something]
end
または、たった1つの命令の場合:
[do something] if val.nil? || val == 0
or
ここでは親子関係を必要とせず、経験豊富なRubyistに完全に自然に読まれます。||
対に噛まれor
たことがあるのは、Perlをプログラムしたことがない人だけです:)
val && val == 0
はより良いと思います。
末尾に疑問符が付いたメソッド名が本当に好きな場合:
if val.nil? || val.zero?
# do stuff
end
他のいくつかのソリューションと同様に、あなたのソリューションは問題ありません。
あなたが注意しなければ、Rubyはあなたにすべてをするためのきれいな方法を探させることができます。
Ruby 2.3.0以降では、安全なナビゲーション演算子(&.
)をNumeric#nonzero?
。と組み合わせることができます。&.
返すnil
インスタンスであった場合nil
とnonzero?
-数であった場合0
:
unless val&.nonzero?
# Is nil or zero
end
または接尾辞:
do_something unless val&.nonzero?
unless val&.nonzero?
ば、「valがゼロまたはゼロの場合」に変換されることを理解するのに少し時間がかかります
do_something if val&.nonzero?
(そうval
でない場合nil
やゼロでない場合)。
まず、それがその特定の状態をチェックできる最も簡潔な方法だと思います。
第二に、私にとってこれはあなたのデザインの潜在的な欠陥を示すコードの臭いです。一般に、nilとzeroは同じことを意味するべきではありません。可能であれば、メソッドの最初または他のメカニズムでチェックすることにより、このコードをヒットする前にvalがnilになる可能性を排除するようにしてください。
これを行う完全に正当な理由があるかもしれません。その場合、コードは適切だと思いますが、可能であれば、少なくともnilチェックを削除することを検討したいと思います。
Object.nilを使用できますか?特にnilをテストします(falseとnilの間に巻き込まれないようにします)。Objectにメソッドをモンキーパッチすることもできます。
class Object
def nil_or_zero?
return (self.nil? or self == 0)
end
end
my_object = MyClass.new
my_object.nil_or_zero?
==> false
Objectへの変更は同僚が追跡するのが難しく、コードが他の人に予測できない可能性があるため、これはお勧めしません。
nil?
と、常にfalseが返されます。nil?
NilClassでのみtrueを返します。
Object
、NilClass
そしてNumeric
。Object
返すfalse
、NilClass
返されるtrue
とNumeric
返すでしょうzero?
。
私のソリューションでは、条件を除いた絞り込みも使用しています。
module Nothingness
refine Numeric do
alias_method :nothing?, :zero?
end
refine NilClass do
alias_method :nothing?, :nil?
end
end
using Nothingness
if val.nothing?
# Do something
end
Railsは、属性クエリメソッドを介してこれを行います。ここで、falseとnilに加えて、0と ""もfalseと評価されます。
if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation
しかし、それは中傷者のシェアを持っています。http://www.joegrossberg.com/archives/002995.html
#attribute
に興味があります、なぜなら私はそのようなものを見つけることができないからです。
できるだけ慣用的にするために、これをお勧めします。
if val.nil? or val == 0
# Do something
end
理由:
短くて明確
[0, nil].include?(val)
val.in? [0,nil]
最短かつ最良の方法は
if val&.>(0)
# do something
end
ためval&.>(0)
valがゼロである場合にも基本的な方法である>ので、それはnilを返し、Rubyで偽に等しいNIL。の場合はfalseを返しますval == 0
。
必要にcase
応じて使用できます。
case val with nil, 0
# do stuff
end
そうすれば、で動作するものなら何でも使用できます===
。これは時々便利です。または、次のようなことを行います。
not_valid = nil, 0
case val1 with *not_valid
# do stuff
end
#do other stuff
case val2 with *not_valid, false #Test for values that is nil, 0 or false
# do other other stuff
end
これは必ずしも良いOOPではありませんが、非常に柔軟性があり、機能します。私if
のは通常、case
とにかくsとして終わります。
もちろんEnum.any?
/Enum.include?
一種の作品も...あなたが本当に謎めいたものになりたいのなら:
if [0, nil].include? val
#do stuff
end
もちろん、正しいことはメソッドまたは関数を定義することです。または、多くの値で同じことを行う必要がある場合は、それらの優れたイテレータを組み合わせて使用します。
クラスにモンキーパッチを適用する代わりに、Ruby2.1以降の改良版を使用できます。改良はモンキーパッチに似ています。その点で、クラスを変更できますが、変更は、使用するスコープに限定されます。
このチェックを1回実行する場合、これはやり過ぎですが、繰り返し実行する場合は、モンキーパッチの代わりになります。
module NilOrZero
refine Object do
def nil_or_zero?
nil? or zero?
end
end
end
using NilOrZero
class Car
def initialize(speed: 100)
puts speed.nil_or_zero?
end
end
car = Car.new # false
car = Car.new(speed: nil) # true
car = Car.new(speed: 0) # true
絞り込みは、ファイルにスコープされるように直前に変更されました。したがって、以前の例ではこれが示されている可能性がありますが、これは機能しません。
class Car
using NilOrZero
end
これは非常に簡潔です。
if (val || 0) == 0
# Is nil, false, or zero.
end
とfalse
同じように扱ってもかまわない限り、機能しますnil
。私が取り組んできたプロジェクトでは、その区別はたまにしか重要ではありません。残りの時間は、個人的にスキップ.nil?
してコードを少し短くすることを好みます。
[更新:私はもうこの種のことを書きません。それは機能しますが、あまりにも不可解です。私はそれをしたいくつかの場所を変えることによって私の悪行を正そうとしました。]
ちなみに、文字列などの.zero?
場合val
は例外が発生するため、使用しませんでした。しかし、.zero?
そうではないことがわかっていれば問題ありません。
[edited]
val
nilの場合、この式は次のように評価されるnil == 0
(したがって、戻るfalse
)と思いました。しかし、私はそれがあまり読みやすいとは思わないが、それは実際に機能しているように見える。
別の解決策:
if val.to_i == 0
# do stuff
end
"5".to_i == 5
、しかしあなたは多かれ少なかれ正しいです。賢いですが、実際には機能しません。
val ||= 0
if val == 0
# do something here
end
val
維持する必要がある場合はどうなりますか?このメソッドを使用して入力データを破壊しているので、nilまたは0をチェックするためのより優れた破壊的でない方法があります。
false
ますか?