2011-04-26 14 views
16

¿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) 
+0

¿No es un rubíista, pero me imagino que forzaría el valor a booleano? – Ethan

+1

Muy relacionado: http://stackoverflow.com/questions/524658/what-does-mean-in-ruby –

Respuesta

20

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.

3

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.

1

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.

Cuestiones relacionadas