Ger Crowley
Ger Crowley

Reputation: 891

how to i call "self.something method" in ruby

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

Answers (4)

Linuxios
Linuxios

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

Lindydancer
Lindydancer

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

Jonathan Julian
Jonathan Julian

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

WarHog
WarHog

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

Related Questions