2010-09-23 4 views
4

Quand il est en effet pas défini, il obtient la valeur nil juste parce qu'il a été « touché » Ruby:« !? Foo = true si elle est définie foo » ne fonctionnera pas comme prévu

$ irb 

ruby-1.9.2-p0 > foo = true if !defined? foo 
=> nil 
ruby-1.9.2-p0 > foo 
=> nil 

ruby-1.9.2-p0 > if !defined? bar 
ruby-1.9.2-p0 ?> bar = true 
ruby-1.9.2-p0 ?> end 
=> true 
ruby-1.9.2-p0 > bar 
=> true 

de sorte que le if ... end fonctionne comme prévu, mais pas foo = true if ....

+0

C'est parce que foo est défini au moment où vous appelez 'defined?'. Je ne vois pas comment cela est inattendu – NullUserException

+0

NullUserException: Donc, il ne fait pas la vérification 'if' en premier? Intéressant. –

Répondre

3

Ruby définit une variable locale juste avant d'exécuter une ligne contenant une affectation. Par conséquent, defined?(foo) sera toujours true pour le doublage.

Un autre exemple montrant que les variables locales sont définies avant une partie de la ligne sont exécutés:

defined? foo # => false 
foo = foo # => foo is now nil 
1

il ne semble raisonnable que [déclaration] si [expression]

est juste réarrangé par la compilateur

si [expression] puis [déclaration] fin

mais on dirait qu'il est manipulé spécialement d'une manière que les pauses définies? en fait, défini ressemble à une construction spéciale (c'est-à-dire pas une fonction normale)

ressemble à si vous l'attribuez dans la même ligne, vous devriez vérifier .nil? à la place:

foo = foo.nil? ? vrai: foo

(cela fonctionne aussi si elle est déjà définie sur false)

1

La façon de penser à ce sujet est:

foo = (true if !defined? foo) 

Alors, d'abord foo est définie, l'expression pour lui donner une valeur est exécutée.

+0

c'est "d'y penser de cette façon", plutôt que de l'exécuter comme ça? –

Questions connexes