pierallard
pierallard

Reputation: 3371

Position of "if" condition

I thought that:

do_something if condition

were equivalent to

if condition
  do_something
end

I found a code that does not respect this rule.

if !(defined? foo)
  foo = default_value
end

Here, foo takes default_value.

foo = default_value if !(defined? foo)

Here, foo takes nil. In the former code, I think if is executed first, and should be equivalent to:

foo = (default_value if !(defined? foo))

Is there any way to set to default_value if the variable is not defined?

General answer :

Some several comments want to use the ||= operator... Which will not work if foo is nil :

foo ||= default_value

will return the default value, while foo is defined.

I insist on using "not defined?", which is not equal to nil.

Upvotes: 1

Views: 120

Answers (2)

deefour
deefour

Reputation: 35370

The Ruby way is

foo ||= default_value

But, of course

if (defined? foo)
  foo = default_value
end

and

foo = default_value if !(defined? foo)

are different. You're not comparing the same thing.

In one you compare (defined? foo) and the other you compare !(defined? foo)

I think what you're really after is the following

if !(defined? foo)
  foo = default_value
end

Upvotes: 5

sawa
sawa

Reputation: 168269

The two pieces of code are equivalent syntactically, but are different from the point of view of parsing. You are partially right that, "if is executed first", but that is only regarding syntax. Within parsing, the parsing order follows the linear order of the tokens. In Ruby, when you have an assignment:

foo = ...

then foo is assigned nil even if that portion of code is not syntactically evaluated, and that affects the result of defined?.

In order to write inline without having that problem, the way I do is to use and, or, &&, or ||:

defined?(foo) or foo = default_value

Upvotes: 3

Related Questions