2010-09-24 12 views
10
>> current_user.first_visit 
=> 0 
>> if current_user.first_visit 
>> puts "test" 
>> end 
test 
=> nil 

¿Por qué se imprime la prueba?¿Por qué no puedo hacer "si es cero" en ruby?

+0

Parece que su pregunta ha sido respondida. Pero debe dejar de usar valores numéricos para verdadero/falso. Utilice las palabras clave verdadero y falso si su idioma es compatible – colithium

+0

Rails ha ampliado el tipo de entero. También puede usar "if current_user.first_visit.zero?" – vise

+1

@vise: '.zero?' Es simple ruby ​​antiguo: [APIdock.com enlace] (http://apidock.com/ruby/v1_8_6_287/Numeric/zero%3F) –

Respuesta

16

En Rubí única nil puede considerarse como análogo a false. No se asume, que 0, "" o [] significa false, por lo que debe utilizar == 0, .blank?, .empty?, .zero?, etc.

Pero nil no siempre se comportan como false. Por ejemplo, en la interpolación de cadenas, se aplica el método .to_s a #{} contenidos, que funciona de forma diferente para FalseClass y NilClass:

irb(main)> "qwe #{false} rty" 
=> "qwe false rty" 
irb(main)> "qwe #{nil} rty" 
=> "qwe rty" 
+1

Tenga en cuenta que '.blank?', '.empty?' son extensiones proporcionadas por Rails framework (a través de 'activesupport') y no están disponibles en Ruby Standard o Core Lib. También el comportamiento diferente es porque "# {falso}" llama al método 'to_s'. – Swanand

+2

@swanand: 'zero?' Y 'empty?' Están en core lib (sin embargo, no estoy seguro de qué clases tenía en mente). –

+0

@ pdom's edit fue correcta. IDK, por qué otros lo rechazaron. http://stackoverflow.com/review/suggested-edits/7845176 – Nakilon

6

Se puede pensar en Ruby, si lo pruebas ya sea un valor lógico, o para la disponibilidad de datos (vs nil). La conversión implícita de 0 a falso admitido por C y (por lo tanto, otros lenguajes como C++) era más un artefacto histórico de días antes de que C tuviera un tipo booleano distinto. Allí, se basa en que 0 es un valor centinela conveniente o que tiene un significado intuitivo. Para muchas cosas (por ejemplo, un país donde los tamaños de las prendas oscilan entre 0 y 8, resultados de llamadas a la función POSC libC), cero no se convierte agradablemente en un booleano lógicamente equivalente, por lo que Ruby no es malo.

Desde esta perspectiva, el problema con su código es que current_user.first_visit - cuyo nombre implica un tipo booleano - en realidad tiene 0 y no es falso. Alternativamente, si usted tenía el current_user.visit_counter claramente numérica, sería natural y correcta de utilizar uno de:

current_user.visit_counter > 0 
current_user.visit_counter >= 1 
current_user.visit_counter != 0 
1

Puede probar este

>> current_user.first_visit 
=> 0 
>> if current_user.first_visit != 0 
>> puts "test" 
>> else 
>> puts "fail" 
>> end 
fail 
=>nil 

Cuando la comprobación de valores numéricos también es necesario iguale con el valor esperado

Cuestiones relacionadas