1

I have been tasked to create an unbeatable tic tac toe opponent for a coding challenge, and I would like to create a Ruby gem to do so, which has proper test coverage and decent Object Oriented Design (OOD).

Having never made my own gem before, and being a new student of proper OOD principles, I found a good blog post that walks through exactly what I need : http://codequizzes.wordpress.com/2013/10/25/creating-a-tic-tac-toe-game-with-ruby/

In defining the Cell class, the following code is given as an example:

module TicTacToe
  class Cell
    attr_accessor :value

    def initialize (value = "")
      @value = value
    end 

  end
end

It seems to me, though, that given the simplicity of this initialization, we could just as easily do this:

module TicTacToe
  class Cell
    attr_accessor :value

    def initialize
      @value = ""
    end 

  end
end

So what's the argument for doing it the first way over the second?

EDIT

Okay, I feel a bit silly now; reading the blog post a bit closer, it clearly says

The Cell class is wrapped in a TicTacToe module to follow Ruby gem conventions and prevent >class name collisions when gems are included in other projects. If Cell is initialized >without any arguments, the cell’s value will be the empty string, but Cell can also be >initialized with an argument. After a cell is instantiated, its value cannot be updated.

However, I am still confused about the last sentence, "After a cell is instantiated, its value cannot be updated."

I would think that is incorrect in this example, as to my understanding, the attr_accessor method makes value both readable and writable -- as it is writable, couldn't I update it by saying

move = Cell.new
move.value = X 
1
  • 1
    The first way makes "" the default value for value, so value => "" for Cell.new, but value => "cat" for Cell.new("cat"). Commented Nov 14, 2014 at 17:35

2 Answers 2

3

First case:

def initialize (value = "")
  @value = value
end

will set the @value to be empty string if no parameter is passed to initialize. If a parameter is passed to initialize, value will be set to that parameter.

Second case:

def initialize
  @value = ""
end 

will always set @value to be the empty string and will not accept parameters.

Example:

If we have

module TicTacToe
  class Cell
    attr_accessor :value
    def initialize (value = "")
      @value = value
    end 
  end
end

c = TicTacToe::Cell.new("hello")
puts c.value

the code would print hello.

Using the same code above but changing the last two lines to

c = TicTacToe::Cell.new
puts c.value    

the code prints nothing (well except the empty string).

Now if we change our code to the second way:

module TicTacToe
  class Cell
    attr_accessor :value
    def initialize
      @value = ""
    end 
  end
end

c = TicTacToe::Cell.new
puts c.value

this will output the empty string again. However, this time if we try changing the last 2 lines to:

c = TicTacToe::Cell.new("hello")
puts c.value

we get an error because the initializer is not expecting an argument. Thus, we cannot instantiate it with any @value besides the empty string.

In regards to your edit:

Yes, you can still change @value. If you would like to prevent this, make it only readable by changing

attr_accessor :value

to

attr_reader :value
Sign up to request clarification or add additional context in comments.

Comments

0

This site actually does a pretty good job of explaiing the pros and cons of doing this both of the ways you've specified above: http://www.rubyist.net/~slagell/ruby/objinitialization.html

For your first example, passing 'value' in as "" as an argument allows you to override this default, whereas your second example forces the '@value' variable to always be "", regardless of changing conditions.

Let me know if this helps.

3 Comments

Offsite links are not good answers for SO. The link could break or change. Can you copy a relevant excerpt of that article into your answer?
interesting link...here is the relevant info: "Flexible initialization ...can use the argument if it is given, or fall back to default values otherwise."
@Jeff - thank you for the feedback on this answer. Going forward, I will provide the link for context but also provide a more robust response to the question that could stand on it's own without the link. Given that an accepted answer has been provided by another user already, and it is consistent with the point I was making, I will leave this as-is. Thank you for the feedback!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.