Frage

Ich suche nach einem kurzen Weg, um einen Wert zu überprüfen, um zu sehen, ob es gleich Null oder gleich Null ist. Zur Zeit mache ich so etwas wie:

if (!val || val == 0)
  # Is nil or zero
end

Aber das scheint sehr ungeschickt.

War es hilfreich?

Lösung

Objekte haben eine nil? Verfahren .

if val.nil? || val == 0
  [do something]
end

Oder für nur eine Anweisung:

[do something] if val.nil? || val == 0

Andere Tipps

Wenn Sie wirklich, wie Methodennamen mit Fragezeichen am Ende:


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

Ihre Lösung ist in Ordnung, wie einige der anderen Lösungen sind.

Rubin können Sie für eine hübsche Weise machen suchen, alles zu tun, wenn du nicht aufpasst.

Zunächst einmal denke ich, dass geht um die knappste Weise, die Sie für diesen bestimmten Zustand überprüfen.

Zweitens, das ist für mich einen Codegeruch, die eine potenzielle Schwachstelle in Ihrem Design zeigt. Im Allgemeinen nil und Null soll nicht das gleiche bedeuten. Wenn möglich, sollten Sie versuchen, die Möglichkeit, val sein null zu beseitigen, bevor Sie diesen Code getroffen, sei es durch, dass zu Beginn des Verfahrens oder einen anderen Mechanismus zu überprüfen.

versuchen, um loszuwerden, die

Sie können einen völlig legitimen Grund müssen dies zu tun, in dem Fall, dass ich Ihr Code denken ist gut, aber ich würde zumindest prüfen Null zu überprüfen, wenn möglich.

von Ruby 2.3.0 weiter, können Sie den sicheren Navigation Operator kombinieren (&.) mit Numeric#nonzero? . &. kehrt nil, wenn die Instanz nil und nonzero? ist - wenn die Zahl ist 0:

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

oder Postfix:

do_something unless val&.nonzero?

Sie können die Object.nil benutzen? für null zu testen, speziell (und nicht bekommen zwischen falschen und nil gefangen). Sie können Affen-Patch als auch ein Verfahren in Objekt.

class Object
   def nil_or_zero?
     return (self.nil? or self == 0)
   end
end

my_object = MyClass.new
my_object.nil_or_zero?
==> false

Dies ist nicht als Änderungen empfohlen, Objekt schwierig für Mitarbeiter zu verfolgen, und können Ihren Code unvorhersehbar anderen.

Ich glaube, Ihr Code ist falsch; es wird für drei Werte in der Tat Test: nil, false , und Null. Dies liegt daran, die !val Ausdruck für alle Werte wahr ist, die falsch sind, die in Ruby ist nil und false.

Das Beste, was ich mit jetzt kommen kann, ist

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

Was natürlich nicht sehr klug, aber (sehr) klar.

nil.to_i gibt Null zurück, so dass ich oft tun:

val.to_i.zero?

Sie werden jedoch eine Ausnahme, wenn val je ein Objekt, das nicht respond_to #to_i der Fall ist.

Meine Lösung auch verwenden Ergebnis, abzüglich der conditionals.

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 tut dies über Attributabfragemethoden, in denen zusätzlich zu falschem und nil, 0 und „“ auch falsch zu bewerten.

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

Allerdings hat es seinen Anteil an Verleumder. http://www.joegrossberg.com/archives/002995.html

Um als idiomatisch wie möglich zu sein, würde ich dies vorschlagen.

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

Denn:

  • Es verwendet die Null? Verfahren.
  • Es nutzt den "oder" Operator, der bevorzugt ist, ||.
  • Es verwendet keine Klammern, die in diesem Fall nicht notwendig sind. Klammern sollten nur verwendet werden, wenn sie einen Zweck, wie zum Beispiel des Überschreiben des Vorrangs bestimmter Operatoren.
  • dienen

Kürzeste und bester Weg, sollten

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

Für val&.>(0) es gibt null, wenn val nil da ist> im Grunde ist auch eine Methode, Null gleich falsch in rubin. Es return false wenn val == 0.

Kurz und klar

[0, nil].include?(val)

ich damit umgehen durch die Definition eines „ist?“ Methode, die ich dann anders auf verschiedene Klassen implementieren kann. Also für Array „ist?“ bedeutet "size> 0"; für Fixnum bedeutet es "self = 0!"; für Streich bedeutet es „selbst! =‚‘“. NilClass, natürlich, definiert „ist?“ wie nur Null zurück.

Sie können case verwenden, wenn Sie mögen:

 case val with nil, 0
      # do stuff
 end

Dann können Sie etwas verwenden, das mit === funktioniert, was schön manchmal ist. Oder etwas tun, wie folgt aus:

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

Es ist nicht gerade gut OOP, aber es ist sehr flexibel und es funktioniert. Mein ifs in der Regel als cases ohnehin enden.

Natürlich Enum.any? / Enum.include? Art auch von funktioniert ... wenn man so will wirklich kryptisch bekommen:

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

Das Richtige zu tun ist natürlich eine Methode oder eine Funktion zu definieren. Oder, wenn Sie die gleiche Sache mit vielen Werten zu tun haben, verwenden Sie eine Kombination dieser schönen Iteratoren.

Ich mag Rails blank? Methode für diese Art von Dingen, aber es wird nicht true für 0 zurück. So können Sie Ihre Methode hinzufügen:

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

Und es wird prüfen, ob irgendein Wert Null ist oder 0:

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

if val.nil_zero?
  #...
end

Anstelle von Affen, der eine Klasse Patchen, könnte verwenden Verfeinerungen in Ruby 2.1 starten. Verfeinerungen sind ähnlich wie Affen Patchen; dass Sie ermöglichen Ihnen, die Klasse zu ändern, aber die Änderung ist begrenzt Sie auf den Umfang wollen es in verwenden.

Das ist übertrieben, wenn Sie diese Prüfung einmal tun wollen, aber wenn Sie sich selbst wiederholen ist es eine gute Alternative zu Affen Patchen.

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

Ergebnis wurde in letzter Minute geändert in die Datei scoped werden. So frühere Beispiele dies gezeigt haben, die nicht funktionieren.

class Car
  using NilOrZero
end

Das ist sehr prägnant:

if (val || 0) == 0
  # Is nil, false, or zero.
end

Es funktioniert, solange Sie nichts dagegen haben, false die gleiche wie nil behandeln. In den Projekten habe ich gearbeitet, nur diese Unterscheidung wichtig ist hin und wieder. Der Rest der Zeit persönlich ziehe ich .nil? überspringen und etwas kürzer Code.

[ Aktualisieren : Ich schreibe nicht diese Art der Sache mehr. Es funktioniert, aber ist zu kryptisch. Ich habe versucht, Recht, meine Untaten zu setzen, indem sie die wenigen Stellen zu ändern, wo ich es tat.]

Übrigens, ich habe nicht .zero? verwenden, da diese eine Ausnahme auslöst, wenn val ist, sagen wir, eine Zeichenfolge. Aber .zero? wäre schön, wenn Sie das ist nicht der Fall wissen.

Dies true ausgewertet für Null und Null: nil.to_s.to_d == 0

unless (val || 0).zero?

    # do stufff

end

Eine andere Lösung:

if val.to_i == 0
  # do stuff
end
val ||= 0
if val == 0
# do something here
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top