Estoy buscando una forma concisa de verificar un valor para ver si es nulo o cero. Actualmente estoy haciendo algo como:
if (!val || val == 0)
# Is nil or zero
end
Pero esto parece muy torpe.
ruby
design-patterns
idioms
null
csexton
fuente
fuente
false
?Respuestas:
¿Los objetos tienen un cero? método .
if val.nil? || val == 0 [do something] end
O, para una sola instrucción:
[do something] if val.nil? || val == 0
fuente
or
no requiere ningún parens aquí, y se leerá de forma completamente natural para un rubyista experimentado. Las únicas personas que alguna vez son mordidas por||
versusor
son las personas que nunca han programado Perl :)val && val == 0
es mejor.Si realmente te gustan los nombres de métodos con signos de interrogación al final:
if val.nil? || val.zero? # do stuff end
Su solución está bien, al igual que algunas de las otras soluciones.
Ruby puede hacerte buscar una manera bonita de hacer todo, si no tienes cuidado.
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
:unless val&.nonzero? # Is nil or zero end
O sufijo:
do_something unless val&.nonzero?
fuente
unless val&.nonzero?
traduce como "si val es nulo o cero"do_something if val&.nonzero?
(también conocido como sival
no esnil
y no es cero).En primer lugar, creo que esa es la forma más concisa de verificar esa condición en particular.
En segundo lugar, para mí, este es un olor a código que indica una falla potencial en su diseño. Generalmente, cero y cero no deberían significar lo mismo. Si es posible, debe intentar eliminar la posibilidad de que val sea nulo antes de acceder a este código, ya sea verificándolo al principio del método o mediante algún otro mecanismo.
Es posible que tenga una razón perfectamente legítima para hacer esto, en cuyo caso creo que su código es bueno, pero al menos consideraría intentar deshacerse de la verificación nula si es posible.
fuente
¿Puede utilizar Object.nil? para probar nil específicamente (y no quedar atrapado entre falso y nil). También puede parchear un método en Object.
class Object def nil_or_zero? return (self.nil? or self == 0) end end my_object = MyClass.new my_object.nil_or_zero? ==> false
Esto no se recomienda ya que los cambios en Object son difíciles de rastrear para los compañeros de trabajo y pueden hacer que su código sea impredecible para otros.
fuente
nil?
siempre devolverá falso.nil?
solo devuelve verdadero en NilClass.Object
,NilClass
yNumeric
.Object
volveríafalse
,NilClass
volveríatrue
yNumeric
volveríazero?
.nil.to_i devuelve cero, así que a menudo hago esto:
Sin embargo, obtendrá una excepción si val alguna vez es un objeto que no responde_to #to_i.
fuente
"5".to_i == 5, but you're more or less right. Clever but doesn't actually work
Creo que tu código es incorrecto; lo hará en la prueba de hecho para tres valores:
nil
,false
y cero. Esto se debe a que la!val
expresión es verdadera para todos los valores que son falsos, que en Ruby esnil
yfalse
.Lo mejor que se me ocurre ahora mismo es
if val == nil || val == 0 # do stuff end
Lo cual, por supuesto, no es muy inteligente, pero (muy) claro.
fuente
Mi solución también usa Refinamientos, menos los condicionales.
module Nothingness refine Numeric do alias_method :nothing?, :zero? end refine NilClass do alias_method :nothing?, :nil? end end using Nothingness if val.nothing? # Do something end
fuente
Rails hace esto a través de métodos de consulta de atributos, donde además de falso y nulo, 0 y "" también se evalúan como falso.
if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation
Sin embargo, tiene su parte de detractores. http://www.joegrossberg.com/archives/002995.html
fuente
#attribute
, porque no puedo encontrar nada de eso.Para ser lo más idiomático posible, sugiero esto.
if val.nil? or val == 0 # Do something end
Porque:
fuente
Corto y claro
[0, nil].include?(val)
fuente
val.in? [0,nil]
El camino más corto y mejor debe ser
if val&.>(0) # do something end
Porque
val&.>(0)
devuelve nil cuando val es nil ya que> básicamente también es un método, nil es igual a falso en ruby. Devuelve falso cuandoval == 0
.fuente
Me ocupo de esto definiendo un "¿es?" método, que luego puedo implementar de manera diferente en varias clases. Entonces, para Array, "es?" significa "tamaño> 0"; para Fixnum significa "self! = 0"; para String significa "self! = ''". NilClass, por supuesto, define "es?" como devolver nada.
fuente
Puede usar
case
si lo desea:case val with nil, 0 # do stuff end
Entonces puedes usar cualquier cosa que funcione
===
, lo cual a veces es bueno. O haz algo como esto:not_valid = nil, 0 case val1 with *not_valid # do stuff end #do other stuff case val2 with *not_valid, false #Test for values that is nil, 0 or false # do other other stuff end
No es exactamente una buena OOP, pero es muy flexible y funciona. Mis
if
s suelen terminar comocase
todos modos, s.Por supuesto
Enum.any?
/Enum.include?
también funciona ... si te gusta ser realmente críptico:if [0, nil].include? val #do stuff end
Por supuesto, lo correcto es definir un método o función. O, si tiene que hacer lo mismo con muchos valores, use una combinación de esos buenos iteradores.
fuente
Me gusta mucho los carriles
blank?
no método para ese tipo de cosas, pero va a volvertrue
a0
. Entonces puedes agregar tu método:def nil_zero? if respond_to?(:zero?) zero? else !self end end
Y comprobará si algún valor es nulo o 0:
nil.nil_zero? => true 0.nil_zero? => true 10.nil_zero? => false if val.nil_zero? #... end
fuente
En lugar de mono parchear una clase, puede usar mejoras a partir de Ruby 2.1. Los refinamientos son similares al parche de mono; en eso, le permiten modificar la clase, pero la modificación se limita al alcance en el que desea usarla.
Esto es excesivo si desea hacer esta verificación una vez, pero si lo repite, es una excelente alternativa a los parches de monos.
module NilOrZero refine Object do def nil_or_zero? nil? or zero? end end end using NilOrZero class Car def initialize(speed: 100) puts speed.nil_or_zero? end end car = Car.new # false car = Car.new(speed: nil) # true car = Car.new(speed: 0) # true
Los refinamientos se cambiaron en el último minuto para ajustarse al alcance del archivo. Así que los ejemplos anteriores pueden haber demostrado esto, lo que no funcionará.
class Car using NilOrZero end
fuente
Esto es muy conciso:
if (val || 0) == 0 # Is nil, false, or zero. end
Funciona siempre que no le importe tratar
false
lo mismo quenil
. En los proyectos en los que he trabajado, esa distinción solo importa de vez en cuando. El resto del tiempo, personalmente prefiero omitir.nil?
y tener un código un poco más corto.[ Actualización : ya no escribo este tipo de cosas. Funciona pero es demasiado críptico. He tratado de corregir mis fechorías cambiando los pocos lugares donde lo hice].
Por cierto, no lo usé
.zero?
ya que esto genera una excepción sival
es, digamos, una cadena. Pero.zero?
estaría bien si sabe que ese no es el caso.fuente
[edited]
Pensé que sival
era nulo, esta expresión se evaluaríanil == 0
(y, por lo tanto, regresaríafalse
). Sin embargo, parece que funciona, aunque no creo que sea muy legible.Esto se evalúa como verdadero para nil y cero:
nil.to_s.to_d == 0
fuente
unless (val || 0).zero? # do stufff end
fuente
Otra solución:
if val.to_i == 0 # do stuff end
fuente
"5".to_i == 5
, pero tienes más o menos razón. Inteligente pero en realidad no funciona.val ||= 0 if val == 0 # do something here end
fuente
val
es necesario mantener el valor en ? Estás superando los datos de entrada con este método, y hay formas mejores y menos destructivas de verificar cero o cero.