Wie man in Ruby null gegen leer gegen leer versteht


1129

Ich finde ich immer wieder für eine klare Definition der Unterschiede zu suchen nil?, blank?und empty?in Ruby on Rails. Hier ist der nächste, den ich gekommen bin:

  • blank?Objekte sind falsch, leer oder eine Leerzeichenfolge. Zum Beispiel "", " ", nil, [], und {}sind leer.

  • nil? Objekte sind Instanzen von NilClass.

  • empty?Objekte sind klassenspezifisch und die Definition variiert von Klasse zu Klasse. Eine Zeichenfolge ist leer, wenn sie keine Zeichen enthält, und ein Array ist leer, wenn sie keine Elemente enthält.

Fehlt etwas oder kann ein genauerer Vergleich durchgeführt werden?


26
Ein Gotcha ist ein leeres Array, für das false zurückgegeben wird present?. Dies liegt daran blank?, dass für ein leeres Array true zurückgegeben wird.
Kris

4
Eine nette Sache ist zu sehen , dass :nil?ist definiert auf ::Kernelund außer Kraft gesetzt auf ::NilClass, während :empty?umgesetzt wird separat auf vielen Klassen (nativ auf ::String, ::Array, ::Hashund nicht nativ auf anderen Klassen wie ::Setaus stdlib und ::ActiveRecord::Relationvon Schienen). Ist :nil?also in allen Unterklassen von ::Objectund auch in jeder Klasse verfügbar , die ::Kernelfür sich selbst enthält, wo :empty?sie implementiert oder speziell in Ihre Klassen aufgenommen werden muss.
Umgeschrieben am

Wenn Sie versuchen, das gesamte nilKonzept zu verstehen, beginnen Sie hier .
Totymedli

[1] pry(main)> [].blank? => true
Michael

Antworten:


1437

.nil? kann für jedes Objekt verwendet werden und ist wahr, wenn das Objekt Null ist.

.empty? kann für Strings, Arrays und Hashes verwendet werden und gibt true zurück, wenn:

  • Stringlänge == 0
  • Array-Länge == 0
  • Hash-Länge == 0

Wenn Sie .empty?auf etwas laufen , das gleich Null ist, wird a geworfen NoMethodError.

Hier .blank?kommt es ins Spiel . Es wird von Rails implementiert und funktioniert mit jedem Objekt sowie mit .empty?Strings, Arrays und Hashes.

nil.blank? == true
false.blank? == true
[].blank? == true
{}.blank? == true
"".blank? == true
5.blank? == false
0.blank? == false

.blank? wertet true auch für Zeichenfolgen aus, die nicht leer sind, aber nur Leerzeichen enthalten:

"  ".blank? == true
"  ".empty? == false

Rails bietet auch .present? , was die Negation von zurückgibt .blank?.

Array gotcha: Gibt blank?zurück, falseauch wenn alle Elemente eines Arrays leer sind. Um zu bestimmen , Geistlosigkeit in diesem Fall der Verwendung all?mit blank?, zum Beispiel:

[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true 

27
Wie in der Frage erwähnt, gelten einige nicht leere Zeichenfolgen als leer.
Andrew Grimm

1
Warum haben sie nil's .empty nicht überschrieben? ob sie .blank hinzufügen könnten?
Bis zum

6
Auch:false.blank? == true
Shannon

2
Ich würde erwähnen presence!
Marc-André Lafortune

2
Beachten Sie, dass dies zu Sicherheitsproblemen führen kann, bei denen ein Angreifer unvorbereiteten Code verwenden kann, der nur nach params.nil sucht. oder es sei denn, params.blank?, und ist der Grund für viele Diskussionen und Arbeiten, die derzeit in Rails ausgeführt werden. Weitere Informationen finden Sie hier: github.com/rails/rails/issues/13420
Houen

675

Ich habe diese nützliche Tabelle mit allen Fällen erstellt:

Geben Sie hier die Bildbeschreibung ein

blank?, present?Sind durch Schienen vorgesehen.


57
Es sollte beachtet werden, dass leer? und anwesend? sind nur Schienen. Sie geben die Ausnahme: NoMethodError in Ruby 2.0.0 zurück.
Lonny Eachus

17
Erwägen Sie das Hinzufügen, any?wenn Sie die Tabelle jemals aktualisieren.
Dennis

blank?und present?sind nicht "nur Rails ", sondern werden automatisch von Rails aufgenommen, können jedoch mithilfe der Core-Erweiterungen von ActiveSupport problemlos in Nicht-Rails-Code aufgenommen werden. Siehe stackoverflow.com/questions/4238867/…
Tin Man

215

Erweitern Sie einfach Julians Tisch:

Geben Sie hier die Bildbeschreibung ein

Ref: leer? Leer? Null? 傻傻 分不清楚


1
@Sibevin Wang, ich habe diese Tabelle heruntergeladen und in einigen meiner Antworten verwendet, um Ihnen die Credits hinzuzufügen. Hoffe es macht dir nichts aus :) Ein großes Lob an diese große Anstrengung!
Lahiru

1
Enumerable#any?ist Vanille Ruby, es sollte nicht unter "Nur Schienen" aufgeführt werden
Daniero

1
@daniero Vielen Dank für Ihre Erinnerung, die Tabelle wird aktualisiert.
Sibevin Wang

Numerische Typen haben auch .zero?und.nonzero?
DaveMongoose

63

Kurzer Tipp: !obj.blank? == obj.present?

Kann in einigen Ausdrücken praktisch / augenschonender sein


Gibt es etwas Äquivalentes zu! obj.nil?
Kirk

present?ist Teil von active_support. Überprüfen Sie hier, was enthalten sein soll, um es zu erhalten: stackoverflow.com/a/4648704/1569
Factor Mystic

2
@ Kirk: !! obj ist gleichbedeutend mit! Obj.nil?
Mohamed Hafez

4
@MohamedHafez Nein, ist es nicht. !!false
Ajedi32

Agh, @ Ajedi32 guter Fang! äquivalent mit dieser einen Ausnahme.
Mohamed Hafez

52

Ein Unterschied besteht darin , dass .nil?und .empty?Methoden sind, die von der Programmiersprache zur Verfügung gestellt werden , Rubin, während .blank?etwas hinzugefügt durch den Web - Entwicklungs - Framework Rails.


49

Geben Sie hier die Bildbeschreibung ein

  • Alles was ist nil?istblank?
  • Alles was ist empty?istblank?
  • Nichts was empty?istnil?
  • Nichts was nil?istempty?

tl; dr - verwenden Sie nur blank?&, es present?sei denn, Sie möchten zwischen ""und unterscheiden" "


2
woah! Du hast meine +1
Am33d

16

Ein Sonderfall ist der Versuch, festzustellen, ob ein Boolescher Wert Null ist:

false.present? == false
false.blank? == true
false.nil? == false

In diesem Fall wäre die Empfehlung zu verwenden .nil?


14

Nur eine kleine Anmerkung zur any?Empfehlung: Er hat Recht, dass es im Allgemeinen gleichbedeutend ist mit !empty?. Kehrt any?jedoch truezu einer Zeichenfolge mit nur Leerzeichen (ala " ") zurück.

Und natürlich auch den obigen Kommentar 1.9.


In Rails ist jede Zeichenfolge, die nur Leerzeichen enthält, "leer": "\ n \ r \ t" .blank? # => true
Lonny Eachus

13

Vergiss nicht, any?was allgemein ist !empty?. In Rails überprüfe ich normalerweise das Vorhandensein von etwas am Ende einer Anweisung mit if somethingoder verwende es unless somethingdann, blank?wo es benötigt wird, da es anscheinend überall funktioniert.


4
.irgendein? funktioniert nicht mit Strings in Ruby 1.9, wie .any? erfordert eine Aufzählung, und die Zeichenfolge # funktioniert in Ruby 1.9 nicht für sich.
Andrew Grimm

4
Vorsicht any?bei der Überprüfung der Nichtleere. Es gibt false zurück, wenn Sie ein Array von falschen Werten haben. Eine Möglichkeit, dies zu umgehen, besteht darin, einen immer zutreffenden Block zu übergeben : [nil, false].any?{ true }, der jedoch !empty?kürzer ist und Sie sich nicht an das seltsame Verhalten erinnern können.
Kelvin

12

nil?ist eine Standard-Ruby-Methode, die für alle Objekte aufgerufen werden kann und zurückgibt, truewenn das Objekt nil:

b = nil
b.nil? # => true

empty?ist eine Standard-Ruby-Methode, die für einige Objekte wie Strings, Arrays und Hashes aufgerufen werden kann und zurückgegeben wird, truewenn diese Objekte kein Element enthalten:

a = []
a.empty? # => true

b = ["2","4"]
b.empty? # => false

empty?kann nicht für nilObjekte aufgerufen werden.

blank?ist eine Rails-Methode, die sowohl für nilObjekte als auch für leere Objekte aufgerufen werden kann .


7

Alle anderen haben gut erklärt, was der Unterschied ist.

Ich möchte Ruby On Rails hinzufügen, es ist besser, obj.blank?oder obj.present?anstelle von obj.nil?oder zu verwenden obj.empty?.

obj.blank?Griffe alle Arten nil, '', [], {}, und kehrt , truewenn Werte nicht zur Verfügung und kehrt sind , falsewenn Werte auf jede Art von Objekt zur Verfügung stehen.


5

exists?Mit dieser Methode kann überprüft werden, ob die Daten in der Datenbank vorhanden sind oder nicht. Es gibt entweder trueoder boolesche Werte zurück false.


Funktioniert nur in der Modellklasse!
Roger

4

Schienen 4

eine Alternative zu @ corban-brooks 'Array gotcha: blank?' um zu überprüfen, ob ein Array nur leere Werte enthält und als leer angesehen werden kann? wahr:

[ nil, '' ].all? &:blank? == true

man könnte auch tun:

[nil, '', "", " ",' '].reject(&:blank?).blank? == true

3

nil?kann für jedes Objekt verwendet werden. Es bestimmt, ob das Objekt einen Wert hat oder nicht, einschließlich 'leerer' Werte.

Zum Beispiel:

example = nil
example.nil?  # true

"".nil?  # false

Grundsätzlich nil?wird nur dann true zurückgegeben, wenn das Objekt tatsächlich gleich 'nil' ist.

empty?wird nur für Objekte aufgerufen, die als Sammlung betrachtet werden. Dazu gehören Zeichenfolgen (eine Sammlung von Zeichen), Hashes (eine Sammlung von Schlüssel / Wert-Paaren) und Arrays (eine Sammlung von beliebigen Objekten).empty?Gibt true zurück, wenn sich keine Elemente in der Sammlung befinden.

Zum Beispiel:

"".empty? # true
"hi".empty?   # false
{}.empty?  # true
{"" => ""}.empty?   # false
[].empty?   # true
[nil].empty?  # false

nil.empty?  # NoMethodError: undefined method `empty?' for nil:NilClass

Beachte das empty? nil-Objekte nicht aufgerufen werden können, da nil-Objekte keine Sammlung sind und eine Ausnahme auslösen.

Beachten Sie auch, dass selbst wenn die Elemente in einer Sammlung leer sind, dies nicht bedeutet, dass eine Sammlung leer ist.

blank?ist im Grunde eine Kombination aus nil?und empty?Es ist nützlich, um Objekte zu überprüfen, von denen Sie annehmen, dass sie Sammlungen sind, könnte aber auch Null sein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.