1

I am a Ruby newbie trying to create a class Timer with the following Rspec:

require 'timer'

describe "Timer" do
  before(:each) do
    @timer = Timer.new
  end

  it "should initialize to 0 seconds" do
    @timer.seconds.should == 0
  end

  describe 'time_string' do
    it "should display 0 seconds as 00:00:00" do
      @timer.seconds = 0
      @timer.time_string.should == "00:00:00"
    end

    it "should display 12 seconds as 00:00:12" do
      @timer.seconds = 12
      @timer.time_string.should == "00:00:12"
    end

    it "should display 66 seconds as 00:01:06" do
      @timer.seconds = 66
      @timer.time_string.should == "00:01:06"
    end

    it "should display 4000 seconds as 01:06:40" do
      @timer.seconds = 4000
      @timer.time_string.should == "01:06:40"
    end
  end

But I don't understand the Rspec's return error message, which says "Timer should initialize to 0 seconds", I am stuck at the beginning with my code and really appreciate anyone who can explain what's wrong with my code below. Thanks.

class Timer
    def intialize(seconds)
        @seconds = seconds
    end
    def seconds=(new_seconds = 0)
        @seconds = new_seconds
    end
    def seconds
        @seconds
    end
end
anh nguyen
  • 29
  • 1
  • 2
    is `initialize` misspelled as `intialize`? – orde Jul 03 '13 at 19:01
  • thanks for pointing that out but i still got the same error message – anh nguyen Jul 03 '13 at 19:05
  • 1
    The Timer `initialize` method requires 1 parameter, but you are passing in none when you do `@timer = Timer.new`. – Justin Ko Jul 03 '13 at 19:06
  • Note that there should be more to the test failure that describes what actually failed. For example, after fixing the `initialize` spelling, the new test failure includes "ArgumentError: wrong number of arguments (0 for 1)". – Justin Ko Jul 03 '13 at 19:08
  • hi Justin, can you be more specific about the parameter? I run @timer.seconds in repl.it and got 0 as return which should satisfy the rspec condition "@timer.seconds.should == 0" – anh nguyen Jul 03 '13 at 19:20
  • Typo and arity issues, especially without stack traces, are unlikely to be useful to future visitors. – Todd A. Jacobs Jul 03 '13 at 22:57

3 Answers3

2

I think your initialize method should take the optional argument:

class Timer
  def initialize(seconds = 0)
    @seconds = seconds
  end
  def seconds=(new_seconds)
    @seconds = new_seconds
  end
end
Stefan
  • 109,145
  • 14
  • 143
  • 218
1

Stefan's answer is good, but I used the below code and it works perfectly for the rest of the problem you are working on.

class Timer
  attr_accessor :seconds

  def initialize
    @seconds = 0
  end
end

The attr_accessor creates the instance variable @seconds, and it is initialized to 0. I cannot take credit for this answer though. I found it and its very thorough explanation on this stackoverflow page: What is attr_accessor in Ruby?

So thank you hakunin.

Community
  • 1
  • 1
Jeremiah McCurdy
  • 592
  • 4
  • 11
0

Trying to solve this in most "lazy" way. Test works fine, but I think there must be short and optimized way to solve it.

class Timer
      attr_accessor  :seconds
  def initialize seconds=0
      @seconds = seconds
  end
  def time_string
      res=[]
      tt=@seconds.div(3600)
      if tt<10
         tt = '0' + tt.to_s
      end
      res.push(tt)
      tt=(@seconds-@seconds.div(3600)*3600).div(60)
      if tt<10
         tt = '0' + tt.to_s
      end
         res.push(tt)
         tt=@seconds-@seconds.div(3600)*3600-((@seconds-@seconds.div(3600)*3600).div(60))*60
      if tt<10
         tt = '0' + tt.to_s
      end
  res.push(tt)
  res.join(':')
  end
end
K.S.A.
  • 1
  • 1