Search code examples
rubyinstance-methods

Splitting program into classes and accessing variables from one class in another


I wrote a tictactoe program, and I am trying to organize it into classes.

class Board
  attr_accessor :fields

  def initialize
    self.fields = {
      '1' => ' ', '2' => ' ', '3' => ' ',
      '4' => ' ', '5' => ' ', '6' => ' ',
      '7' => ' ', '8' => ' ', '9' => ' '
    }
  end
  def set_stone_at(position, stone)
    fields[position] = stone
  end
  def stone_at(position)
    stone = fields[position]
    puts stone
  end
  def show
    puts fields
  end
end

class Game
  attr_accessor :board

  def initialize
    self.board = Board.new
  end
  def print_board
    puts "\n  #{fields['1']} | #{fields['2']} | #{fields['3']}"
    puts "  --*---*---"
    puts "  #{fields['4']} | #{fields['5']} | #{fields['6']}"
    puts "  --*---*---"
    puts "  #{fields['7']} | #{fields['8']} | #{fields['9']} \n"
  end
end

board = Board.new
board.show
Game.new.board.show
game = Game.new
game.board.set_stone_at('1', 'X')
game.board.set_stone_at('2', 'O')
game.print_board

I am having trouble accessing the variable fields from class Board in class Game. I am getting the error:

in `print_board': undefined local variable or method `fields' for #<Game:0x007ffc1a895710> (NameError)

I would appreciate any kind of help. I am grateful for any help and explanations.


Solution

  • Sorry, responding in a mobile phone. From glancing over this, it looks like you want to have self.board.fields in your print_board method in game. Fields is an accessor on the Board class. You'll want to send it to an instance of the board class. In Game you have an accessor, board, that has an instance of the board in it available, if initialize runs. So you'll want to make sure you instantiate game if you want that available. Looks like you did do that. You might also try @board.fields in your print method. I think that will also work with the board accessor you made.

    -- Adding this in after getting to a real computer. This has to do a lot with 'self' in Ruby. You already seem to have a good basic grasp on how to get started here, and even though, as @WandMaker mentioned, it would be easier to make a #print method off board, I'm glad you did it this way. 'self in ruby' will turn up a lot of worthwhile related posts. For a broader context/better learning experience I also recommend 'The Well Grounded Rubyist'. I think you will also get a great understanding of this and other very useful stuff if you learn some meta programming. For that, 'Meta-Programming Ruby' from PragProgs is good, and so are the metaprogramming lessons on Ruby Monk http://rubymonk.com/learning/books/.

    'Practical Object Oriented Ruby' by Sandi Metz may be best, but I haven't read it yet. Want to...

    Gotta go!