Ich suche nach einer präzisen Möglichkeit, einen Wert zu überprüfen, um festzustellen, ob er Null oder Null ist. Zur Zeit mache ich so etwas wie:
if (!val || val == 0)
# Is nil or zero
end
Aber das scheint sehr ungeschickt.
ruby
design-patterns
idioms
null
csexton
quelle
quelle
false
?Antworten:
Objekte haben eine Null? Methode .
if val.nil? || val == 0 [do something] end
Oder für nur eine Anweisung:
[do something] if val.nil? || val == 0
quelle
or
erfordert hier keine Parens und wird einem erfahrenen Rubyisten ganz natürlich vorlesen. Die einzigen Menschen , die jemals gebissen werden durch||
Vergleichor
sind Menschen , die nie Perl programmiert haben :)val && val == 0
ist besser.Wenn Sie Methodennamen mit Fragezeichen am Ende wirklich mögen:
if val.nil? || val.zero? # do stuff end
Ihre Lösung ist in Ordnung, ebenso wie einige der anderen Lösungen.
Ruby kann Sie dazu bringen, nach einem hübschen Weg zu suchen, um alles zu tun, wenn Sie nicht vorsichtig sind.
quelle
Ab Ruby 2.3.0 können Sie den sicheren Navigationsoperator (
&.
) mit kombinierenNumeric#nonzero?
.&.
Gibt zurück,nil
wenn die Instanz warnil
undnonzero?
- wenn die Nummer war0
:unless val&.nonzero? # Is nil or zero end
Oder Postfix:
do_something unless val&.nonzero?
quelle
unless val&.nonzero?
um zu verstehen, was übersetzt "wenn val null oder null ist" bedeutetdo_something if val&.nonzero?
(auch bekannt als ifval
is notnil
und not zero).Zunächst einmal denke ich, dass dies die präziseste Art ist, wie Sie nach dieser bestimmten Bedingung suchen können.
Zweitens ist dies für mich ein Code-Geruch, der auf einen möglichen Fehler in Ihrem Design hinweist. Im Allgemeinen sollten Null und Null nicht dasselbe bedeuten. Wenn möglich, sollten Sie versuchen, die Möglichkeit auszuschließen, dass val Null ist, bevor Sie diesen Code drücken, indem Sie dies entweder zu Beginn der Methode oder durch einen anderen Mechanismus überprüfen.
Möglicherweise haben Sie einen absolut legitimen Grund, dies zu tun. In diesem Fall halte ich Ihren Code für gut, aber ich würde zumindest in Betracht ziehen, den Null-Check nach Möglichkeit loszuwerden.
quelle
Sie können die Object.nil? spezifisch auf Null zu testen (und nicht zwischen falsch und Null gefangen zu werden). Sie können eine Methode auch in Object patchen.
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 wird nicht empfohlen, da Änderungen an Object für Mitarbeiter schwer nachzuvollziehen sind und Ihr Code für andere möglicherweise unvorhersehbar ist.
quelle
nil?
würde immer false zurückgeben.nil?
Gibt nur in der NilClass true zurück.Object
,NilClass
undNumeric
.Object
würde zurückkehrenfalse
,NilClass
würde zurückkehrentrue
undNumeric
würde zurückkehrenzero?
.nil.to_i gibt Null zurück, deshalb mache ich das oft:
Sie erhalten jedoch eine Ausnahme, wenn val jemals ein Objekt ist, das nicht auf #to_i reagiert.
quelle
"5".to_i == 5, but you're more or less right. Clever but doesn't actually work
Ich glaube, Ihr Code ist falsch. es wird für drei Werte in der Tat Test:
nil
,false
und null. Dies liegt daran, dass der!val
Ausdruck für alle Werte wahr ist, die falsch sind, was in Rubynil
und istfalse
.Das Beste, was ich mir gerade einfallen lassen kann, ist
if val == nil || val == 0 # do stuff end
Was natürlich nicht sehr klug ist, aber (sehr) klar.
quelle
Meine Lösung verwendet auch Verfeinerungen abzüglich der Bedingungen.
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
quelle
Rails tut dies über Attributabfragemethoden, wobei neben false und nil auch 0 und "" als false ausgewertet werden.
if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation
Es hat jedoch seinen Anteil an Kritikern. http://www.joegrossberg.com/archives/002995.html
quelle
#attribute
, weil ich so etwas nicht finden kann.Um so idiomatisch wie möglich zu sein, würde ich dies vorschlagen.
if val.nil? or val == 0 # Do something end
Weil:
quelle
Kurz und klar
[0, nil].include?(val)
quelle
val.in? [0,nil]
Der kürzeste und beste Weg sollte sein
if val&.>(0) # do something end
Denn
val&.>(0)
es gibt nil zurück, wenn val nil ist, da> im Grunde auch eine Methode ist, nil gleich false in ruby. Es gibt false zurück, wennval == 0
.quelle
Ich gehe damit um, indem ich ein "ist?" Methode, die ich dann auf verschiedenen Klassen unterschiedlich implementieren kann. Also für Array "ist?" bedeutet "Größe> 0"; für Fixnum bedeutet es "self! = 0"; für String bedeutet es "self! = ''". NilClass definiert natürlich "ist?" als nur Null zurück.
quelle
Sie können verwenden,
case
wenn Sie möchten:case val with nil, 0 # do stuff end
Dann können Sie alles verwenden, was funktioniert
===
, was manchmal schön ist. Oder machen Sie so etwas: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
if
s endet normalerweisecase
sowieso als s.Natürlich
Enum.any?
/Enum.include?
Art funktioniert auch ... wenn Sie wirklich kryptisch werden möchten:if [0, nil].include? val #do stuff end
Das Richtige ist natürlich, eine Methode oder Funktion zu definieren. Wenn Sie dasselbe mit vielen Werten tun müssen, verwenden Sie eine Kombination dieser netten Iteratoren.
quelle
Ich mag Rails
blank?
Methode für diese Art von Dingen, aber es wird nicht wiedertrue
für0
. So können Sie Ihre Methode hinzufügen:def nil_zero? if respond_to?(:zero?) zero? else !self end end
Und es wird geprüft, ob ein Wert Null oder 0 ist:
nil.nil_zero? => true 0.nil_zero? => true 10.nil_zero? => false if val.nil_zero? #... end
quelle
Anstatt eine Klasse mit Affen zu patchen, können Sie ab Ruby 2.1 Verfeinerungen verwenden . Verfeinerungen ähneln dem Patchen von Affen. Auf diese Weise können Sie die Klasse ändern, die Änderung ist jedoch auf den Bereich beschränkt, in dem Sie sie verwenden möchten.
Dies ist übertrieben, wenn Sie diese Überprüfung einmal durchführen möchten, aber wenn Sie sich wiederholen, ist dies eine großartige Alternative zum Affen-Patching.
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
Die Verfeinerungen wurden in letzter Minute geändert , um sie in die Datei aufzunehmen. Frühere Beispiele haben dies möglicherweise gezeigt, was jedoch nicht funktioniert.
class Car using NilOrZero end
quelle
Das ist sehr prägnant:
if (val || 0) == 0 # Is nil, false, or zero. end
Es funktioniert so lange, wie es Ihnen nichts ausmacht,
false
dasselbe zu behandeln wienil
. In den Projekten, an denen ich gearbeitet habe, ist diese Unterscheidung nur gelegentlich von Bedeutung. Den Rest der Zeit überspringe ich persönlich lieber.nil?
und habe etwas kürzeren Code.[ Update : Ich schreibe so etwas nicht mehr. Es funktioniert, ist aber zu kryptisch. Ich habe versucht, meine Missetaten zu korrigieren, indem ich die wenigen Stellen geändert habe, an denen ich es getan habe.]
Übrigens habe ich nicht verwendet,
.zero?
da dies eine Ausnahme auslöstval
, wenn es sich beispielsweise um eine Zeichenfolge handelt. Aber.zero?
wäre in Ordnung, wenn Sie wissen, dass dies nicht der Fall ist.quelle
[edited]
Ich dachte, wennval
Null wäre, würde dieser Ausdruck zunil == 0
(und damit zurückkehrenfalse
) führen. Es scheint jedoch, dass es tatsächlich funktioniert, obwohl ich es nicht für sehr lesbar halte.Dies ergibt für null und null den Wert true:
nil.to_s.to_d == 0
quelle
unless (val || 0).zero? # do stufff end
quelle
Eine andere Lösung:
if val.to_i == 0 # do stuff end
quelle
"5".to_i == 5
, aber du hast mehr oder weniger recht. Clever, funktioniert aber nicht.val ||= 0 if val == 0 # do something here end
quelle
val
beibehalten werden muss? Mit dieser Methode werden die Eingabedaten überlastet, und es gibt bessere, weniger zerstörerische Möglichkeiten, um auf Null oder Null zu prüfen.