I came across an odd bug in my code that revealed an interesting behavior of ruby. Hopefully someone can explain why it behaves this way.
I had a class with an instance variable @foo and a method that referenced a locally scoped variable foo. I refactored part of the method out accidentally leaving the reference to foo; the variable no longer defined in the scope. It ended up pointing to @foo instead. Changing foo made changes to @foo and vice versa.
Simplified version: EDIT : added ImOutOfNames.
class ImOutOfNames
attr_accessor :foo # the culprit!
end
class Bar < ImOutOfNames
def initialize
@foo = "that is a tasty burger"
end
def bar_method_1
foo = "Come on Yolanda, whats Fonzie like?"
bar_method_2
end
def bar_method_2
puts foo
end
end
And the output of bar_method_1 and bar_method_2 was "that is a tasty burger". I was expecting there to be an error, for example running the above code gets
NameError: undefined local variable or method
I even had a more senior developer come take a look and he was somewhat baffled and confirmed the behavior.
Is this an expected behavior and I misunderstood how @variables work or is there something wrong?
Your previous buggy code probably at an attr_accessor definition that created a method foo that accessed to your instance variable,
You can have the same behavior if your code is like this:
class Bar
attr_accessor :foo
def initialize
@foo = "that is a tasty burger"
end
def bar_method_1
foo = "Come on Yolanda, whats Fonzie like?"
bar_method_2
end
def bar_method_2
puts foo
end
end
The attr_accessor call defines two methods in your object;
def foo
@foo
end
def foo=(value)
@foo = value
end
So in your case, when no local variable was defined, the method was used, but as you did not call attr_accessor in this example you posted the method was not defined and there was no local variable to use on bar_method_2 so the call fails.