a
Ici, vous évaluez a
, ce qui n'est pas défini. Par conséquent, vous obtenez une exception.
a || 1
Ici, vous encore doivent évaluer a
pour déterminer la valeur de l'expression booléenne. Tout comme ci-dessus, a
n'est pas défini. Par conséquent, vous obtenez une exception.
a = a || 1
Ici, a
est défini. Il est défini comme étant une variable locale non initialisée. Dans Ruby, les variables non initialisées sont évaluées à nil
, donc le côté droit de l'expression d'affectation est nil || 1
, ce qui donne 1
, donc la valeur de retour de l'expression d'affectation est 1
et l'effet secondaire est que a
est initialisé à 1
.
EDIT: Il semble qu'il y ait une certaine confusion sur le moment où les variables sont définies et quand elles sont initialisées dans Ruby. Le get est défini à parse l'heure mais initialisé à runtime. Vous pouvez le voir ici:
foo # => NameError: undefined local variable or method `foo' for main:Object
foo
est indéfini.
if false
foo = 'This will never get executed'
end
À ce stade, foo
est défini, même si la ligne ne sera jamais exécutée. Le fait que la ligne ne soit jamais exécutée est complètement hors de propos, car l'interpréteur n'a rien à voir avec cela: les variables locales sont définies par l'analyseur, et l'analyseur voit évidemment cette ligne.
foo # => nil
Il n'y a pas d'erreur, parce que foo
est défini, et il évalue à nil
parce qu'il est non initialisée.
Duplication de http://stackoverflow.com/questions/1462407/ruby-edge-cases –