I have difficulties understanding the setter and how to apply the value in use.
In the below example,
def time_string=(seconds)
@time_string = calculator(seconds)
end
How can I get the seconds' value from setter?
Thanks a lot
class Timer
def seconds
@seconds = 0
end
def time_string
@time_string
end
def seconds=(t)
@seconds = t
end
def time_string=(seconds)
@time_string = calculator(seconds)
end
def calculator(x)
array = []
sec = (x % 60).to_s
min = ((x / 60 ) % 60).to_s
hour = (x / 3600).to_s
temp = [hour, min, sec]
temp.map {|i| i.length < 2 ? array.push("0#{i}") : array.push("#{i}") }
array.join(":")
end
end
I think I get what you're trying to accomplish. First, all that calculate code...why? Why not use the methods in the
Timeclass? Second, there are not such thing as setters in Ruby. Everything in Ruby is a method. So technically, what you call a setter is a method that acts like a setter. In your code, both methodsseconds=andsecondsact as a setter (the first sets@secondsto the return value of thecalculatorcall, and the second method sets@secondsto 0).You can't get the seconds value from a setter method, the purpose of a setter method is, after all, to SET something. If you want to get something, use a getter method. And it's pretty simple to create a getter method, just change your
secondsmethod to this:Ruby can create this method automatically in the background for you with just one line added inside your class, and that line is
attr_reader :seconds. Each time you see this in some Ruby code, assume that what Ruby does in the background is generate something similar to thesecondsmethod above. In the same fashion, if you want Ruby to also automatically generate a setter method code like this:then use
attr_writer :seconds. These attr_reader and attr_writer methods exist because making setter and getter methods is so common that this shortens your program significantly, especially if you have, say, 10 instance variables (you have@secondsand@time_stringnow , but you could also have instance variables for minutes, hours, days, etc. that would be a lot of methods for getting/setting the instance variables!). In the same fashion, you could also create a getter method automatically for@time_stringas well:But NOT a setter method because your set logic for
@time_stringis kinda different than the method Ruby would create (attr_reader and attr_writer create simple getter/setter methods), if you typeattr_writer :time_string, then Ruby would create this method in the background:which is not what you want. You can simplify your code a lot, here's my version:
You could also further simplify this code by using
attr_accessorfor seconds, for that I recommend this excellent answer which explains more about these shortcuts.