Ruby

Undefined local variables and conditions in Ruby


Ruby’s dynamic nature can sometimes be confusing. Consider this example, what do you expect to be returned?

 # `active?` returns `false` for this example.
active = false if invoice.active?

{ active: active }

Since the condition is false, you might expect active to not be set and throw an error, like calling an undefined local variable normally would:

irb(main):001:0> active
NameError (undefined local variable or method `active' for main:Object)

But Ruby actually initializes the variable. It just doesn’t set a value because the condition returns false. This means active is nil in this case!

irb(main):004:0> { active: active }
=> {:active=>nil}

This can lead to unexpected behavior, for example when passing a hash into a Rails model. A better usage would be to use the boolean method directly inside the hash:

{ active: invoice.active? }

Side note: undefined instance variables always return nil.