Comprobando si una variable no es nula y no es cero en rubí


Respuestas:


428
a menos que discount.nil? || descuento == 0
  # ...
final

31
Use 'o' en lugar de ||
Orion Edwards

93
@ orion-edwards ¿por qué?
NARKOZ

39
Usar 'o' es peligroso. 'o' tiene una presencia de operador menor que '=', por lo que lo siguiente tiene un comportamiento inesperado: a = falso o verdadero #a es falso después de esta declaración
Tom G

20
@xiy actualmente la guía recomienda fingir o y y no existen (|| es eso o && y?)
usuario3125280

67
Soportes actuales de la "Guía de estilo Ruby" The and and or keywords are banned. It's just not worth it. Always use && and || instead.. Y es correcto, por razones de David y 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

Tenga cuidado con los descargos de responsabilidad habituales ... gran poder / responsabilidad, parches de mono que conducen al lado oscuro, etc.


28

ok, después de 5 años han pasado ...

if discount.try :nonzero?
  ...
end

Es importante tener en cuenta que tryestá definido en la gema ActiveSupport, por lo que no está disponible en ruby ​​simple.


77
Tenga en cuenta que esta es una respuesta específica de rieles . El rubí de vainilla no tiene un trymétodo.
Tom Lord

Correcto. Aunque se parece más a ActiveSupport específico, que es una dependencia mucho más ligera y ampliamente utilizada que los rieles completos. De todos modos, ahora la respuesta de @ ndn es la correcta.
reescrito el

Editado para usar navegación segura
reescrito el

1
La respuesta ahora duplica stackoverflow.com/a/34819818/1954610 ... Creo que tiene valor dejarlo como trypara mostrar la opción alternativa (¡esta es la razón por la que se votó en primer lugar!), Siempre que sea claro El lector que ActiveSupportno es vainilla rubí.
Tom Lord

Punto tomado, la respuesta rodada hacia atrás.
reescrito el

27
a menos que [nil, 0] .include? (descuento) 
  # ...
final

13
¿Hermoso? Si. ¿Legible? Realmente no.
El Ninja Trepador

1
Encuentro esto perfectamente legible, y preferiría que fuera una nueva clase. Bien hecho.
colincr

El enfoque más rubí de manejar dos condiciones.
Yugendran

23

Desde Ruby 2.3.0 en adelante, puede combinar el operador de navegación segura ( &.) con Numeric#nonzero?. &.devuelve nilsi la instancia fue nily nonzero?- si el número fue 0:

if discount&.nonzero?
  # ...
end

O postfix:

do_something if discount&.nonzero?

"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String.... Esto no es seguro de usar en objetos arbitrarios.
Tom Lord

2
@TomLord, como se indicó en el comentario anterior, esto no estaba destinado a trabajar con objetos arbitrarios. En cambio, se refiere al caso cuando tiene algo que sabe que debería ser un número, pero también podría serlo nil.
ndnenkov

Dejaría ese hecho claro en la respuesta, en lugar de que alguien lea esto y no vea el descargo de responsabilidad en los comentarios.
Tom Lord

@TomLord, se indica en la respuesta " nonzero?- si el número era 0" . Además, la necesidad de verificar si un objeto completamente arbitrario 0surge extremadamente rara vez en comparación con eso para verificar un número que puede o no ser nil. Por lo tanto, está casi implícito. Incluso si alguien de alguna manera asume lo contrario, comprenderá instantáneamente lo que está sucediendo cuando intente ejecutarlo.
ndnenkov


15

Podrías hacer esto:

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

El orden es importante aquí, porque si discountes así nil, entonces no tendrá un zero?método. discount.zero?Sin embargo, la evaluación de cortocircuito de Ruby debería evitar que intente evaluar , si discountes así nil.


11

¿Puede convertir su fila vacía a un valor entero y verificar cero?

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

cuidado: 0.1.to_i == 0
Simon B.

3
if discount and discount != 0
  ..
end

actualización, lo hará falseparadiscount = false


2

Puede aprovechar el método NilClassproporcionado #to_i, que devolverá cero para los nilvalores:

unless discount.to_i.zero?
  # Code here
end

Si discountpueden ser números fraccionarios, puede usarlos #to_fpara evitar que el número se redondee a cero.


¿No es esto lo mismo que la respuesta de @ oivoodo?
Cary Swoveland

No funciona para objetos arbitrarios . "".to_i == "foo".to_i == "0".to_i == 0. Su método hará todo tipo de coacciones de tipo no intencionadas. También fallará con un NoMethodErrorif discountque no responde to_i.
Tom Lord

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

Si pasamos "", ¿devolverá falso mientras está en blanco? devuelve verdadero Igual es el caso cuando data = false blank? devuelve verdadero para nil, falso, vacío o una cadena de espacio en blanco. Entonces, ¿es mejor usar en blanco? método para evitar una cadena vacía también.


1
blank?es un método específico para rieles y no está disponible en vainilla rubí.
Tom Lord

¡¡Estás en lo correcto!! Pensé que esto está relacionado con la etiqueta "ror" que se publicó aquí. Mi error. Esto no va a funcionar en vainilla rubí.
Saroj

1

Cuando trato con un registro de base de datos , me gusta inicializar todos los valores vacíos con 0, usando el asistente de migración:

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

0

Puede inicializar el descuento a 0 siempre que se garantice que su código no intente usarlo antes de que se inicialice. Supongo que eso eliminaría un cheque, no puedo pensar en otra cosa.



0

Prefiero usar un enfoque más limpio:

val.to_i.zero?

val.to_idevolverá a 0si val es a nil,

después de eso, todo lo que tenemos que hacer es verificar si el valor final es cero .


-1

La solución alternativa es usar Refinamientos, así:

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

Creo que lo siguiente es lo suficientemente bueno para el código ruby. No creo que pueda escribir una prueba unitaria que muestre alguna diferencia entre esto y el original.

if discount != 0
end

8
Se evaluaría truesi el descuento fuera nil.
Andrew Grimm
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.