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
classObjectdef nil_zero?self.nil?||self==0endend# which lets you donil.nil_zero?# returns true0.nil_zero?# returns true1.nil_zero?# returns false"a".nil_zero?# returns falseunless 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.
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
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:
"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.
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.
¿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 ==0end
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.
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.
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.
discount
es falso?discount.in? [0, nil]
la forma más limpia posibleRespuestas:
fuente
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.Tenga cuidado con los descargos de responsabilidad habituales ... gran poder / responsabilidad, parches de mono que conducen al lado oscuro, etc.
fuente
ok, después de 5 años han pasado ...
Es importante tener en cuenta que
try
está definido en la gema ActiveSupport, por lo que no está disponible en ruby simple.fuente
try
método.try
para mostrar la opción alternativa (¡esta es la razón por la que se votó en primer lugar!), Siempre que sea claro El lector queActiveSupport
no es vainilla rubí.fuente
Desde Ruby 2.3.0 en adelante, puede combinar el operador de navegación segura (
&.
) conNumeric#nonzero?
.&.
devuelvenil
si la instancia fuenil
ynonzero?
- si el número fue0
:O postfix:
fuente
"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String
.... Esto no es seguro de usar en objetos arbitrarios.nil
.nonzero?
- si el número era0
" . Además, la necesidad de verificar si un objeto completamente arbitrario0
surge extremadamente rara vez en comparación con eso para verificar un número que puede o no sernil
. 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.fuente
Podrías hacer esto:
El orden es importante aquí, porque si
discount
es asínil
, entonces no tendrá unzero?
método.discount.zero?
Sin embargo, la evaluación de cortocircuito de Ruby debería evitar que intente evaluar , sidiscount
es asínil
.fuente
¿Puede convertir su fila vacía a un valor entero y verificar cero?
fuente
actualización, lo hará
false
paradiscount = false
fuente
Puede aprovechar el método
NilClass
proporcionado#to_i
, que devolverá cero para losnil
valores:Si
discount
pueden ser números fraccionarios, puede usarlos#to_f
para evitar que el número se redondee a cero.fuente
"".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 unNoMethodError
ifdiscount
que no respondeto_i
.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.
fuente
blank?
es un método específico para rieles y no está disponible en vainilla rubí.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:
fuente
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.
fuente
fuente
Prefiero usar un enfoque más limpio:
val.to_i
devolverá a0
si val es anil
,después de eso, todo lo que tenemos que hacer es verificar si el valor final es cero .
fuente
La solución alternativa es usar Refinamientos, así:
fuente
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.
fuente
true
si el descuento fueranil
.