Verifica se una variabile non è nulla e non è zero in rubino


Risposte:


428
a meno che discount.nil? || sconto == 0
  # ...
fine

31
Utilizzare "o" anziché ||
Orion Edwards,

93
@ orion-edwards perché?
NARKOZ,

39
L'uso di "o" è pericoloso. 'o' ha una presenza dell'operatore inferiore rispetto a '=', quindi quanto segue ha un comportamento imprevisto: a = falso o vero #a è falso dopo questa affermazione
Tom G

20
@xiy attualmente la guida raccomanda di fingere o e e non esistere (|| è questo o && e?)
user3125280

67
Stand attuali "Ruby Style Guide" The and and or keywords are banned. It's just not worth it. Always use && and || instead.. Ed è giusto, per ragioni di David e Tom.
Andre Figueiredo,

40
class Object
  def nil_zero?
    self.nil? || self == 0
  end
end

# which lets you do
nil.nil_zero? # returns true
0.nil_zero?   # returns true
1.nil_zero?   # returns false
"a".nil_zero? # returns false

unless discount.nil_zero?
  # do stuff...
end

Attenzione ai soliti disclaimer ... grande potere / responsabilità, patching delle scimmie che portano al lato oscuro ecc.


28

ok, dopo 5 anni sono passati ....

if discount.try :nonzero?
  ...
end

È importante notare che tryè definito nella gemma ActiveSupport, quindi non è disponibile in rubino semplice.


7
Questa è una risposta specifica per le rotaie . Il rubino alla vaniglia non ha un trymetodo.
Tom Lord,

Corretta. Sebbene sia più simile a ActiveSupport specifico, che è una dipendenza molto più leggera e ampiamente utilizzata rispetto alle guide complete. Comunque ora la risposta di @ ndn è quella giusta.
riscritto il

Modificato per utilizzare la navigazione sicura
riscritto il

1
La risposta ora duplica stackoverflow.com/a/34819818/1954610 ... Penso che ci sia valore nel lasciarlo tryper mostrare l'opzione alternativa (ecco perché è stato votato in primo luogo!), Purché sia ​​chiaro il lettore che ActiveSupportnon è rubino alla vaniglia.
Tom Lord,

Punto preso, risposta annullata.
riscritto il

27
salvo [nil, 0] .include? (sconto) 
  # ...
fine

13
Bellissimo? Sì. Leggibile? Non proprio.
El Ninja Trepador,

1
Lo trovo perfettamente leggibile e lo preferirei a una nuova classe. Molto bene.
Colincr

L'approccio più rubyist per gestire due condizioni.
Yugendran,

23

Da Ruby 2.3.0 in poi, è possibile combinare l'operatore di navigazione sicura ( &.) con Numeric#nonzero?. &.ritorna nilse l'istanza era nile nonzero?- se il numero era 0:

if discount&.nonzero?
  # ...
end

O postfisso:

do_something if discount&.nonzero?

"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String.... Questo non è sicuro da usare su oggetti arbitrari.
Tom Lord,

2
@TomLord, come affermato nel commento precedente, non si intendeva lavorare con oggetti arbitrari. Invece si tratta del caso in cui hai qualcosa che sai dovrebbe essere un numero, ma potrebbe anche esserlo nil.
ndnenkov,

Vorrei chiarire questo fatto nella risposta, piuttosto che qualcuno che legga questo messaggio e non osserva il disclaimer nei commenti.
Tom Lord,

@TomLord, è indicato nella risposta " nonzero?- se il numero fosse 0" . Inoltre, la necessità di verificare se un oggetto completamente arbitrario si 0presenta estremamente raramente rispetto a quella per verificare un numero che può o non può essere nil. Quindi è quasi implicito. Anche se qualcuno in qualche modo fa il contrario, capiranno immediatamente cosa sta succedendo quando provano a eseguirlo.
ndnenkov,


15

Potresti farlo:

if (!discount.nil? && !discount.zero?)

L'ordine è importante qui, perché se lo discountè nil, allora non avrà un zero?metodo. La valutazione del corto circuito di Ruby dovrebbe impedirgli di provare a valutare discount.zero?, se lo discountè nil.


11

È possibile convertire la riga vuota in valore intero e controllare zero ?.

"".to_i.zero? => true
nil.to_i.zero? => true

attenzione: 0.1.to_i == 0
Simon B.

3
if discount and discount != 0
  ..
end

aggiornamento, lo farà falseperdiscount = false


2

Puoi sfruttare il metodo NilClassfornito #to_i, che restituirà zero per i nilvalori:

unless discount.to_i.zero?
  # Code here
end

Se discountpossono essere numeri frazionari, è possibile utilizzare #to_finvece, per evitare che il numero venga arrotondato a zero.


Non è la stessa della risposta di @oivoodo?
Cary Swoveland,

Non funziona per oggetti arbitrari . "".to_i == "foo".to_i == "0".to_i == 0. Il tuo metodo renderà ogni tipo di coercizione di tipo non intenzionale. Fallirà anche con un NoMethodErrorif discountnon risponde to_i.
Tom Lord,

2
def is_nil_and_zero(data)
     data.blank? || data == 0 
end  

Se passiamo "" restituirà false mentre è vuoto? ritorna vero. Lo stesso vale quando data = false blank? restituisce vero per zero, falso, vuoto o una stringa di spazi bianchi. Quindi è meglio usare il bianco? metodo per evitare anche stringhe vuote.


1
blank?è un metodo specifico per binari e non disponibile in rubino vaniglia.
Tom Lord,

Hai ragione!! Ho pensato che questo fosse correlato al tag "ror" così pubblicato qui. Errore mio. Questo non funzionerà nel rubino vaniglia.
Saroj

1

Quando ho a che fare con un record di database , mi piace inizializzare tutti i valori vuoti con 0, usando l'helper di migrazione:

add_column :products, :price, :integer, default: 0

0

È possibile inizializzare lo sconto su 0 a condizione che il codice sia garantito per non tentare di utilizzarlo prima che venga inizializzato. Ciò toglierebbe un controllo, suppongo, non riesco a pensare ad altro.



0

Preferisco usare un approccio più pulito:

val.to_i.zero?

val.to_irestituirà a 0se val è a nil,

dopo ciò, tutto ciò che dobbiamo fare è verificare se il valore finale è zero .


-1

La soluzione alternativa è utilizzare i perfezionamenti, in questo modo:

module Nothingness
  refine Numeric do
    alias_method :nothing?, :zero?
  end

  refine NilClass do
    alias_method :nothing?, :nil?
  end
end

using Nothingness

if discount.nothing?
  # do something
end

-7

Credo che quanto segue sia abbastanza buono per il codice ruby. Non credo di poter scrivere un test unitario che mostri alcuna differenza tra questo e l'originale.

if discount != 0
end

8
Valuterebbe truese lo sconto fosse nil.
Andrew Grimm,
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.