¿Alguien puede decirme por qué muchos métodos booleanos de Ruby usan esta convención de doble negación?Convención de doble negación boina Ruby
!!(boolean expression)
¿Alguien puede decirme por qué muchos métodos booleanos de Ruby usan esta convención de doble negación?Convención de doble negación boina Ruby
!!(boolean expression)
La doble negación asegura que no importa el valor inicial, siempre se obtendrá true
o false
, no algún valor misterio.
Esto es práctico porque evita las referencias pendientes a los objetos que ya no necesita, o al tener que diferenciar entre dos tipos de valores falsos, nil
y false
.
A menudo verá métodos escritos así:
def logged_in?
[email protected]_user
end
Esto devolverá true
o false
y ese valor puede ser utilizado para cualquier propósito que se requiere. Compare eso con esto:
def logged_in?
@session_user
end
En este caso, si se guarda el valor, en realidad se está ahorrando todo el @session_user
objeto, que podría ser un trozo bastante grande de memoria. Esta memoria no puede liberarse hasta que su referencia quede fuera del alcance. Dado que solo hay un true
y un false
, no es necesario que recoja basura.
Supongamos que quiere definir un método que devuelva un valor booleano. Por ejemplo, si una cadena coincide con una expresión regular.
class String
def include? regex; self =~ regex end
end
Si haces lo anterior, se volverá nil
cuando no coincide, y un entero cuando coincide. En muchos casos, eso no importa tanto (nil
es similar a false
y true
se puede sustituir por un número entero). Pero si realmente quería un valor lógico como valor de retorno, si lo hace
class String
def include? regex; !!(self =~ regex) end
end
volverá true
cuando coincide, false
cuando no lo hace.
En mi opinión, Ruby es demasiado inteligente sobre Booleanos. Esta es una solución para los casos en que la astucia causa problemas.
Aquí está la astucia excesiva: no hay clase booleana. En su lugar, existe una convención según la cual cualquier valor puede servir como booleano. En un contexto donde se requiere un valor verdadero o falso, nil
o false
significa "falso" y cualquier otra cosa significa "verdadero". Los valores true
y false
no son parte de una clase especial, son los únicos miembros de sus respectivas clases — que existen solo para hacer que el código sea un poco más legible.
supongo que esto funciona bien la mayor parte del tiempo, pero de vez en mucho tiempo que necesita un valor booleano que es siempre true
o false
. Por ejemplo, recientemente necesité comparar dos valores booleanos y hacer algo especial si fueran diferentes; el único problema es que uno de ellos era true
o false
, mientras que el otro era 1 o nil
. ¿Fijar? Utilice el hecho de que !!nil == false
y !!1 == true
.
¿No es un rubíista, pero me imagino que forzaría el valor a booleano? – Ethan
Muy relacionado: http://stackoverflow.com/questions/524658/what-does-mean-in-ruby –