Reputation: 238
I have this block of code:
class CallMe
attr_accessor :a, :b, :c
def self.start(*args)
self.new(*args).get_answer
end
def initialize(a,b,c)
@a = a
@b = b
@c = c
end
def get_answer
if c
b = nil
else
return b
end
end
end
answer = CallMe.start(1,2,nil)
Why when i run it in irb i always get answer = nil
even logic case is get b value that is 2
Upvotes: 4
Views: 184
Reputation: 2877
Variable Hoisting effect is used in many languages. For Ruby it is described in the official documentation:
The local variable is created when the parser encounters the assignment, not when the assignment occurs
So, get_answer
method creates local variable b
regardless to value of c
. And assigns local variable b
to nil
while creating. Then get_answer
returns local variable b
which is always nil
.
Correct method:
def get_answer
c ? self.b = nil : b
end
Upvotes: 3
Reputation: 1900
That's because in context of if
statement you actually redefine b
when you type b = nil
. For Ruby, it's not clear either you want to call object's method :b
or to create a new variable b
. In such cases, priority always goes from the global to the closest context, in this case - to context inside of if
block.
If you'll change
if c
b = nil
else
return b
end
# to
if c
# b = nil
# or
self.b = nil
else
return b
You'll notice it works as you expected.
Upvotes: 0