Question

I just learned Ruby within the past month, and am working on my TDD skills with RSpec.

I am trying to get the following test to pass:

    it "has a modified color" do
    @phone.color = "green"

    puts @phone.color.should == "green"
end

Here is my code:

    class Phone

      attr_reader   :name
      attr_reader   :manufacturer
      attr_accessor :color

      def initialize(name, manufacturer)
        @name           = name
        @manufacturer   = manufacturer
      end

      def color(color='black')
        @color = color
      end
    end

I am trying to do the following essentially:

    phone = Phone.new("Moto X", "Motorola")
    puts phone.color # 'black'
    phone.color = "green"
    puts phone.color # 'green'

However, it is still outputting 'black' after I try reassigning the color to green, please help.

Thanks.

Was it helpful?

Solution

The problem is that your def color is an attribute reader not a writer. So it will always return the default color, black, per the parameter.

When you do the assignment:

phone.color = "green"

It is calling the implicit writer (generated by attr_accessor :color). An attribute writer would look like:

def color=(c)
  @color = c
end

After writing the color to 'green', you attempt to access via:

puts phone.color

This will execute the attribute reader:

def color(c='black')
  @color=c
end

Which sets the color to 'black' and returns that color.

If you want a default black color, you can define your class like this:

class Phone
  attr_reader   :name
  attr_reader   :manufacturer
  attr_accessor :color         # This generates your reader and writer methods

  def initialize(name, manufacturer)
    @name           = name
    @manufacturer   = manufacturer
  end

  def color
    @color || 'black'    # If @color is nil, return 'black', otherwise @color
  end
end

2.0.0-p195 :012 > phone = Phone.new("Moto X", "Motorola")
 => #<Phone:0x9ecc1ac @name="Moto X", @manufacturer="Motorola">
2.0.0-p195 :013 > phone.color
 => "black"
2.0.0-p195 :014 > phone.color = "green"
 => "green"
2.0.0-p195 :015 > phone.color
 => "green"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top