I have been using Ruby for a while. Now i'm going to dig deeper and find all answers to questions that i have. I hope i will find answer to this one here. So here is my question in code below:
class Game
attr_accessor :in_progress
def initialize
@in_progress = false
end
def start!
# debug info
puts self.inspect # => #<Game:0x8f616f4 @in_progress=false>
puts self.class.instance_methods(false) # => [:in_progress, :in_progress=, :start!]
puts self.instance_variables # => [:@in_progress]
puts self.respond_to?("in_progress=") # => true
puts in_progress # => true - getter works without self
# main quesion
in_progress = true # Why setter doesn't work without self?
# self.in_progress = true # this would work and set @in_progress to true becase setter called
# @in_progress = true # this would work as well because we set instance variable to true directly
end
end
g = Game.new
g.start!
puts g.in_progress # => false - setter in start! method didn't work
What we have here:
I read about method lookup in Ruby (Go one step to the right into the receiver's class, and then up the ancestors chain, until you find the method.) But i really don't know why i have to use self.in_progress=true to get access to setter method. Especially when getter method works without self.
Thanks in advance!
Because you are assigning value to local variable in_progress
in a function, not the instance variable. The getter works because Ruby will query the local namespace of the start!
function for in_progress
, it will not find it and then it will query the instance namespace and it will find a method called in_progress
and will call it.
There is no way Ruby interpreter can find out whether you want to assign the true
value in a local in_progress
or on the instance variable, so the rule is to assign it locally (to the current namespace in start!
).
When you do in_progress = true
, you actually create a local variable inside your method and not accessing your setter.
When you do puts in_progress
, Ruby checks for an in_progress
local variable and when it cant find it, it goes for the getter of your class.
Try doing in_progress = 'hello'
and then do puts in_progress
. You will realize that Ruby is going to use the local variable in_progress
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With