2010-09-24 5 views
1

J'ai remarqué cette petite bizarrerie (je pense) dans If Statements in Ruby. Voici un exemple:Étrange Ruby If Statement Question

my_number = nil 
if my_number < 3 
    'number is less than 3' 
end 

De toute évidence, lorsque vous exécutez ce code, vous obtiendrez une « comparaison des Fixnum avec zéro a échoué » erreur. Maintenant, voici quelque chose d'étrange. Si je fais un petit changement dans la déclaration If pour vérifier zéro, cela fonctionne bien. Exemple:

my_number = nil 
if my_number && my_number < 3 
    'number is less than 3' 
end 

L'ajout de la vérification de zéro l'empêche de se bloquer. Cela peut sembler stupide mais je n'arrive pas à comprendre pourquoi cela fonctionne. Ne devrait-il pas encore jeter une erreur?

Merci à tous ceux qui peuvent expliquer cela. :) Merci!

Répondre

4

Les expressions booléennes sont évaluées selon ce que l'on appelle le mode "court-circuit". C'est-à-dire, dès qu'il connaît le résultat, il n'essaie plus d'évaluer les expressions.

Donc, il fait le if my_number et puisqu'il s'agit de false, il n'est pas nécessaire de continuer, car false && <anything> est toujours faux. Ceci est une fonctionnalité de langue utile, et beaucoup de langages fonctionnent comme ceci (le Visual Basic original est une exception à laquelle je peux penser) parce qu'il vous permet de faire exactement ce genre de test sans avoir besoin de fastidieux imbriqués.

0

Il doit être OK pour tester pour zéro, alors if nil ou quelque chose comme ça est OK dans presque toutes les langues. Mais pour une comparaison arithmétique, si elle ne lançait pas une exception, elle devrait renvoyer vrai ou faux. De toute façon est problématique.

vrai genre de ne pas de sens, comme nul serait à la fois < et> que 3.

Faux est presque aussi mauvais, comme aujourd'hui nil < 3 et nil >= 3 sont à la fois faux, et ce n'est pas idéal. Par conséquent, la méthode de comparaison génère une exception. Problème résolu.

1

Ceci n'est pas spécifique à Ruby: j'ai remarqué ce comportement dans toutes les langues que j'ai jamais utilisées, de Pascal à Java.

Si vous avez l'expression booléenne b1 && b2 && b3 ... && bn, la plupart des langues garantir que bi seront évalués de gauche à droite et si certains bi se révèle être false, l'évaluation sera arrêté. (parce que l'expression entière est fausse alors). Idem pour l'opérateur booléen ||.

0

nil est "falsifié". Essayez ceci dans irb:

irb(main):001:0> puts "Nil is true " if nil 
=> nil 
irb(main):002:0> puts "Nil is not true " if !nil 
Nil is not true 
=> nil 

nul n'est pas la même chose que de faux, mais ce qui en fait agir en tant que telle aide beaucoup dans les boucles et d'autres tests:

false == nil 
=> false 

Depuis la première partie de votre et est faux ruby ​​fait la chose paresseuse et ne prend même pas la peine d'évaluer le prochain bit, si c'est> 3.

0

Ce qui se passe est appelé évaluation de court-circuit.Vous êtes en train déclaration peut être considérée comme ceci:

if(my_number) 
    if(my_number < 3) 
    'number is less than 3' 
    end 
end 

Depuis la première condition est fausse, il n'y a aucune raison d'évaluer la deuxième condition de la déclaration - la my_number < 3 parties.