Come capire zero contro vuoto vs vuoto in Ruby


1129

Mi ritrovo a volte alla ricerca di una definizione chiara delle differenze di nil?, blank?e empty?in Ruby on Rails. Ecco il più vicino che sono venuto:

  • blank?gli oggetti sono falsi, vuoti o una stringa di spazi bianchi. Ad esempio, "", " ", nil, [], e {}sono vuoti.

  • nil? gli oggetti sono istanze di NilClass.

  • empty?gli oggetti sono specifici della classe e la definizione varia da classe a classe. Una stringa è vuota se non ha caratteri e una matrice è vuota se non contiene elementi.

Manca qualcosa o si può fare un confronto più stretto?


26
Un gotcha è un array vuoto che restituisce false per present?. Questo perché blank?restituisce true per un array vuoto.
Kris

4
Una cosa bella è vedere che :nil?è definito su ::Kernele sovrascritto su ::NilClass, mentre :empty?è implementato separatamente su molte classi (in modo nativo su ::String, ::Array, ::Hash, e non in modo nativo su altre classi come ::Setda stdlib e ::ActiveRecord::Relationda rotaie). Quindi :nil?è disponibile in tutte le sottoclassi ::Objecte anche in ogni classe che include ::Kernelda sola, dove :empty?deve essere implementata o inclusa specificamente nelle tue classi.
riscritto il

Se provi a capire l'intero nilconcetto, inizia qui .
totymedli,

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

Risposte:


1437

.nil? può essere utilizzato su qualsiasi oggetto ed è vero se l'oggetto è zero.

.empty? può essere utilizzato su stringhe, array e hash e restituisce true se:

  • Lunghezza stringa == 0
  • Lunghezza matrice == 0
  • Lunghezza hash == 0

Correre .empty?su qualcosa che è zero lancerà a NoMethodError.

È qui che .blank?entra in gioco. È implementato da Rails e funzionerà su qualsiasi oggetto, oltre a funzionare come .empty?su stringhe, array e hash.

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

.blank? valuta anche true su stringhe che non sono vuote ma contengono solo spazi bianchi:

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

Rails fornisce anche .present? , che restituisce la negazione di .blank?.

Array gotcha: blank?restituirà falseanche se tutti gli elementi di un array sono vuoti. Per determinare il vuoto in questo caso, utilizzare all?con blank?, ad esempio:

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

27
Come indicato nella domanda, alcune stringhe non vuote vengono considerate vuote.
Andrew Grimm,

1
Perché non hanno sovrascritto nil's .empty? se potessero aggiungere .blank?
tillda

6
Inoltre:false.blank? == true
Shannon,

2
Vorrei menzionare presence!
Marc-André Lafortune,

2
Come aggiunta al gotcha all-blank-array di cui Tom parla nella sua risposta, tieni presente che ciò può portare a problemi di sicurezza in cui un utente malintenzionato può utilizzare un codice non preparato che controlla semplicemente a meno che params.nil? o a meno che params.blank ?, ed è la causa di molte discussioni e lavori attualmente in Rails. Vedi qui per maggiori informazioni: github.com/rails/rails/issues/13420
Houen,

675

Ho realizzato questa utile tabella con tutti i casi:

inserisci qui la descrizione dell'immagine

blank?, present?sono forniti da Rails.


57
Va notato che vuoto? e presente? sono solo Rails. Restituiscono Eccezione: NoMethodError in Ruby 2.0.0.
Lonny Eachus,

17
Valuta di aggiungere any?se aggiorni mai la tabella.
Dennis,

blank?e present?non sono " solo Rails ", sono automaticamente inclusi da Rails ma possono essere facilmente inclusi nel codice non Rails utilizzando le estensioni Core di ActiveSupport. Vedi stackoverflow.com/questions/4238867/…
Tin Man

215

Basta estendere il tavolo di Julian:

inserisci qui la descrizione dell'immagine

Rif: vuoto? Vuoto? Zero? 傻傻 分不清楚


1
@ Sibevin Wang, ho scaricato questa tabella e l'ho usata in alcune delle mie risposte aggiungendo i crediti a te. Spero non ti dispiaccia :) Complimenti per questo grande sforzo!
Lahiru,

1
Enumerable#any?è Vanilla Ruby, non dovrebbe essere elencato sotto "rails only"
daniero

1
@daniero Grazie per il tuo promemoria, la tabella è stata aggiornata.
Sibevin Wang,

Anche i tipi numerici hanno .zero?e.nonzero?
DaveMongoose,

63

Suggerimento veloce: !obj.blank? == obj.present?

Può essere utile / più facile per gli occhi in alcune espressioni


c'è qualcosa di equivalente a! obj.nil?
Kirk,

present?fa parte di active_support, controlla qui cosa includere per ottenerlo: stackoverflow.com/a/4648704/1569
Factor Mystic

2
@Kirk: !! obj è equivalente a! Obj.nil?
Mohamed Hafez,

4
@MohamedHafez No non lo è. !!false
Ajedi32,

Eh, @ Ajedi32 buona cattura! equivalente con quell'unica eccezione.
Mohamed Hafez,

52

Una differenza è che .nil?e .empty?sono metodi che vengono forniti dal linguaggio di programmazione Ruby, mentre .blank?è qualcosa di aggiunto dai Rails framework di sviluppo web.


49

inserisci qui la descrizione dell'immagine

  • Tutto ciò che è nil?èblank?
  • Tutto ciò che è empty?èblank?
  • Nulla empty?ènil?
  • Nulla nil?èempty?

tl; dr: usa solo blank?& a present?meno che tu non voglia distinguere tra ""e" "


2
woah! hai ottenuto il mio +1
Am33d

16

Un caso speciale è quando si cerca di valutare se un valore booleano è zero:

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

In questo caso la raccomandazione sarebbe quella di utilizzare .nil?


14

Solo una piccola nota sulla any?raccomandazione: ha ragione, è generalmente equivalente !empty?. Tuttavia, any?tornerà truea una stringa di solo spazi bianchi (ala " ").

E, naturalmente, vedi anche il commento 1.9 sopra.


In Rails, qualsiasi stringa contenente solo caratteri di spazi bianchi è "vuota": "\ n \ r \ t" .blank? # => true
Lonny Eachus,

13

Non dimenticare any?quale è generalmente !empty?. In Rails in genere controllo la presenza di qualcosa alla fine di un'istruzione con if somethingo unless somethingquindi utilizzo blank?dove necessario poiché sembra funzionare ovunque.


4
.qualunque? non funziona con le stringhe in ruby ​​1.9, come .any? richiede enumerabile e stringa # ciascuno da solo non funziona in ruby ​​1.9.
Andrew Grimm,

4
Attento any?a controllare la non vacuità. Restituisce falso se si dispone di una matrice di valori falsi. Un modo per aggirare questo è quello di passare un blocco sempre vero:, [nil, false].any?{ true }ma !empty?è più corto e non ricordi lo strano comportamento.
Kelvin,

12

nil?è un metodo Ruby standard che può essere chiamato su tutti gli oggetti e restituisce truese l'oggetto è nil:

b = nil
b.nil? # => true

empty?è un metodo Ruby standard che può essere chiamato su alcuni oggetti come Stringhe, Array e Hash e restituisce truese questi oggetti non contengono alcun elemento:

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

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

empty?non può essere chiamato su niloggetti.

blank?è un metodo Rails che può essere chiamato sia su niloggetti che su oggetti vuoti.


7

Tutti gli altri hanno spiegato bene qual è la differenza.

Vorrei aggiungere Ruby On Rails, è meglio usare obj.blank?o obj.present?invece diobj.nil? o obj.empty?.

obj.blank?gestisce tutti i tipi nil, '', [], {}, e torna truese i valori non sono disponibili e rendimenti falsese i valori sono disponibili su qualsiasi tipo di oggetto.


5

exists?Il metodo può essere utilizzato per verificare se i dati esistono nel database o meno. Restituisce valori booleani trueo false.


Funziona solo sulla classe del modello!
Roger,

4

Rotaie 4

un'alternativa al 'Array gotcha: blank?' di @ corban-brook per verificare se un array contiene solo valori vuoti e può essere considerato vuoto? vero:

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

si potrebbe anche fare:

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

3

nil?può essere utilizzato su qualsiasi oggetto. Determina se l'oggetto ha qualche valore o meno, compresi i valori "vuoti".

Per esempio:

example = nil
example.nil?  # true

"".nil?  # false

Fondamentalmente nil?restituirà vero solo se l'oggetto è effettivamente uguale a "zero".

empty?viene chiamato solo su oggetti considerati una raccolta. Ciò include cose come stringhe (una raccolta di caratteri), hash (una raccolta di coppie chiave / valore) e matrici (una raccolta di oggetti arbitrari). empty?restituisce true se non ci sono articoli nella raccolta.

Per esempio:

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

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

Nota che empty?non può essere chiamato su oggetti nil poiché gli oggetti nil non sono una raccolta e genereranno un'eccezione.

Si noti inoltre che anche se gli elementi in una raccolta sono vuoti, ciò non significa che una raccolta sia vuota.

blank?è fondamentalmente una combinazione di nil?ed empty?è utile per controllare gli oggetti che si presume siano raccolte, ma potrebbero anche essere nulli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.