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] endO, para una sola instrucción:
[do something] if val.nil? || val == 0fuente
orno 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||versusorson las personas que nunca han programado Perl :)val && val == 0es mejor.Si realmente te gustan los nombres de métodos con signos de interrogación al final:
if val.nil? || val.zero? # do stuff endSu 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?.&.devuelvenilsi la instancia fuenilynonzero?- si el número fue0:unless val&.nonzero? # Is nil or zero endO 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 sivalno esnily 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? ==> falseEsto 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,NilClassyNumeric.Objectvolveríafalse,NilClassvolveríatrueyNumericvolverí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 workCreo que tu código es incorrecto; lo hará en la prueba de hecho para tres valores:
nil,falsey cero. Esto se debe a que la!valexpresión es verdadera para todos los valores que son falsos, que en Ruby esnilyfalse.Lo mejor que se me ocurre ahora mismo es
if val == nil || val == 0 # do stuff endLo 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 endfuente
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 derivationSin 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 endPorque:
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 endPorque
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
casesi lo desea:case val with nil, 0 # do stuff endEntonces 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 endNo es exactamente una buena OOP, pero es muy flexible y funciona. Mis
ifs suelen terminar comocasetodos 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 endPor 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 volvertruea0. Entonces puedes agregar tu método:def nil_zero? if respond_to?(:zero?) zero? else !self end endY 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? #... endfuente
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) # trueLos 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 endfuente
Esto es muy conciso:
if (val || 0) == 0 # Is nil, false, or zero. endFunciona siempre que no le importe tratar
falselo 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 sivales, digamos, una cadena. Pero.zero?estaría bien si sabe que ese no es el caso.fuente
[edited]Pensé que sivalera 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 == 0fuente
unless (val || 0).zero? # do stufff endfuente
Otra solución:
if val.to_i == 0 # do stuff endfuente
"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 endfuente
vales 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.