tags:

views:

64

answers:

3

When it is in fact not defined, it gets the value nil just because it was "touched":

$ 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 

so the if ... end works as expected, but foo = true if ... doesn't.

+2  A: 

Ruby defines a local variable just before executing a line containing an assignment, so defined?(foo) will always be true for the one-liner.

Another example showing that local variables are defined before any part of the line are executed:

defined? foo # => false
foo = foo    # => foo is now nil
Marc-André Lafortune
A: 

it does sound reasonable that [statement] if [expression]

is just rearranged by the compiler to

if [expression] then [statement] end

but it looks like it's handled specially in a way which breaks defined? actually, defined looks like a special construct (i.e. not a normal function)

looks like if your assigning it in the same line you should check for .nil? instead:

foo = foo.nil? ? true : foo

(this also works if it's already set to false)

dominic
A: 

The way to think about this is:

foo = (true if !defined? foo)

So, first foo is defined, then the expression to give it a value is run.

Andrew Vit
this is "to think about it as this way", rather than it actually executing like this?
動靜能量