質問

値が nil か 0 かを確認する簡潔な方法を探しています。現在、私は次のようなことをしています:

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

他のヒント

最後に疑問符が付いたメソッド名が本当に好きな場合:


if val.nil? || val.zero?
  # do stuff
end

他のいくつかのソリューションと同様に、あなたのソリューションは問題ありません。

Rubyを使用すると、気をつけなければ、すべてを実行するためのきれいな方法を検索できます。

まず最初に、それがその特定の状態をチェックできる最も簡潔な方法だと思います。

第二に、これはデザインの潜在的な欠陥を示すコードの匂いです。一般に、nilとzeroは同じことを意味するべきではありません。可能であれば、このコードをヒットする前に、メソッドの先頭またはその他のメカニズムでチェックすることにより、valがnilになる可能性を排除するようにしてください。

これを行う完全に正当な理由があるかもしれません。その場合、コードは良いと思いますが、可能であれば、nilチェックを取り除くことを検討することを少なくとも検討します。

Ruby 2.3.0以降では、安全なナビゲーション演算子(&。)と Numeric#nonzero? &。は、インスタンスが nil nonzero?の場合 nil を返します-数字が 0の場合

unless val&.nonzero?
  # Is nil or zero
end

または後置:

do_something unless val&.nonzero?

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 、およびゼロの3つの値をテストします。これは、!val 式がfalseのすべての値に対してtrueであるためです。Rubyでは、これは nil および false です。

私が今思いつくことができる最高のものは

if val == nil || val == 0
  # do stuff
end

もちろん、それほど賢いわけではありませんが、(非常に)明確です。

nil.to_iはゼロを返すので、私はこれをよくします:

val.to_i.zero?

ただし、valが#to_iに応答しないオブジェクトである場合、例外が発生します。

私のソリューションでは、条件を除いた絞り込みも使用しています。

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と""また、偽と評価されます。

if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation

ただし、中傷者の割合があります。 http://www.joegrossberg.com/archives/002995.html

可能な限りイディオムにするには、これをお勧めします。

if val.nil? or val == 0
    # Do something
end

理由:

  • nilを使用しますか?メソッド。
  • 「または」を使用します; ||。
  • よりも望ましい演算子
  • この場合は必要ない括弧を使用しません。括弧は、特定の演算子の優先順位をオーバーライドするなど、何らかの目的に役立つ場合にのみ使用してください。

最短かつ最良の方法

if val&.>(0)
  # do something
end

val&。>(0)の場合 valがnilの場合は>からnilを返します。基本的にメソッドでもあり、ルビーではnilはfalseに等しい。 val == 0 の場合はfalseを返します。

短縮してクリア

[0、nil] .include?(val)

「is?」を定義してこれに対処します;このメソッドは、さまざまなクラスで異なる方法で実装できます。配列の場合、「is?」は「サイズ> 0」を意味します。 Fixnumでは、「自己!= 0」を意味します。 Stringの場合は、" self!= ''"を意味します。もちろん、NilClassは「is?」を定義します;単にnilを返すように。

使用できます 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とにかく。

もちろん Enum.any?/Enum.include? ある種の作品も...本当に不可解なことを知りたい場合は、次のようにします。

if [0, nil].include? val
    #do stuff
end

もちろん、メソッドまたは関数を定義するのが正しいことです。または、多くの値に対して同じことを実行する必要がある場合は、これらの優れたイテレータを組み合わせて使用​​します。

Railsの blank?メソッドはそのようなことを本当に好きですが、 0 の場合は true を返しません。メソッドを追加できます:

def nil_zero? 
  if respond_to?(:zero?) 
    zero? 
  else 
    !self 
  end 
end 

そして、ある値がnilか0かをチェックします:

nil.nil_zero?
=> true
0.nil_zero?
=> true
10.nil_zero?
=> false

if val.nil_zero?
  #...
end

クラスにモンキーパッチを適用する代わりに、使用できますRuby 2.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?で問題ありません。

これは、nilおよびゼロに対してtrueと評価されます。 nil.to_s.to_d == 0

unless (val || 0).zero?

    # do stufff

end

別の解決策:

if val.to_i == 0
  # do stuff
end
val ||= 0
if val == 0
# do something here
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top