开发者

Ruby's "foo = true if !defined? foo" won't work as expected

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.


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


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)


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜