Reputation: 891
when i call the MyClock.tick method it give me an "undefined method 'tick' for # " Error
how do i call a method that has "self.something" as the method name, or is that not the problem here?
class Clock
attr_accessor :hours, :mins, :secs, :time
def initialize file_name
@time = IO.readlines("clock.dat")
@hours = @time[0].to_i # change values in array to ints
@mins = @time[1].to_i
@secs = @time[2].to_i
end
def self.tick
@sec = @sec + 1 # add on sec to the clock
if @secs > 59
@mins = @mins + @secs/60 # change to min from sec
@secs = 0 + @secs%60
end
if @mins > 59
@hours = @hours + @hours/60 #change to hour from min
@mins = 0 + @mins%60
end
if @hours > 23 #make sure not more then 24 hours
@hours = 0 + @hours%24
end
end
def self.to_s
puts ("#{@hours}:#{@mins}:#{@secs}") # prints time
end
end
MyClock = Clock.new "clock.dat"
MyClock.tick
MyClock.to_s
Upvotes: 0
Views: 2792
Reputation: 35783
To begin, Ruby conduct says to never use constants for local variables like you just did. A capital letter at the beginning of an identifier makes it a constant.
When you declare your tick
method, you are declaring it as a class method, which means it would be called with Clock.tick
rather than my_clock.tick
. If you want the method to be used with my_clock.tick
, remove the self.
in the method name.
Upvotes: 0
Reputation: 26094
The "best" way (or, rather, the least bad) that I've found is to retrieve the class of the object using the 'class' method, then call the self-method. For example:
class Clock
def self.tick
puts "This is self.tick"
end
# Example of call from non-self function to a self-function.
def test
# Note: Call from a member function needs the "self.", otherwise
# "class" will be interpreted as the keyword "class".
self.class.tick
end
end
my_clock = Clock.new
my_clock.test
# Example of a call to a class-self-function from an object.
my_clock.class.tick
Update: One can, of course, call Clock.tick
. However, explicitly specifying the class name when one does not have to makes things like refactoring harder. This is also the reason why class methods often are defined using def self.tick
rather than def Clock.tick
.
Upvotes: 0
Reputation: 12264
First, name your instance variable with all lower case:
my_clock = Clock.new "clock.dat"
Next, fix class/instance methods. You probably want an instance method:
def tick
instead of class method
def self.tick
Upvotes: 2
Reputation: 8710
You're trying to call class method from objects. Use this:
Clock.tick
if you want to call class method, or this
class Clock
def tick
end
end
Clock.new.tick
to call instance method
Upvotes: 0