0

I am trying to let a method initiate multiple instances of another class.

class Players
  def initialize(players)
    @players = players
  end
  def generate_boards
    @players.each do |player|
      board = BingoBoardGenerator.new
      player = BingoBoard.new(player, board.generate)
      p player
    end
  end
end

players = ["Nick","Jiyoon","Mae","Lawson","Matthew"]
plays = Players.new(players)
plays.generate_boards

p player shows that five instances of BingoBoard were created properly, but I am not sure how to access them (or where they are). Any help on how to call these instances? Normally I would do:

nick = BingoBoard.new("Nick", board.generate) 
nick.board

but when I instantiate them all together, I don't know how to set/access their instance name.

sawa
  • 165,429
  • 45
  • 277
  • 381
Nick P
  • 20
  • 3
  • *If* returning an array of boards from "generate boards", then one could use `boards = plays.generate_boards; boards[0].player`, eg. *As it currently is the function returns no useful value.* I would suggest looking into [`Array#map`](http://ruby-doc.org/core-2.2.0/Array.html#method-i-map) and using it instead of each.. – user2864740 Aug 25 '15 at 22:08
  • Thanks, I see what you are saying about setting the variable boards = to the generating boards. I rearranged my code a bit and I think I have the right idea now. – Nick P Aug 25 '15 at 22:21

1 Answers1

0

As indicated by user2864740, you can use :map instead of :each to return an array of BingoBoard instances. If you wanted to store those instances to use later, you can use memoization as shown below. The first time :bingo_board_instances is called, the boards will be generated and the instance variable @bingo_board_instances will be set so that future invocations of :bingo_board_instances will not result in the generation of new boards.

class Players
  def initialize(players)
    @players = players
  end

  def generate_boards
    @players.map do |player|
      board = BingoBoardGenerator.new
      BingoBoard.new(player, board.generate)
    end
  end

  def bingo_board_instances
    @bingo_board_instances ||= generate_boards
  end
end

While the above code works just fine, I think the more intuitive solution would be to have a Player class (instead of Players) and then pass in an array of Player instances when initializing a BingoBoardGenerator. With this approach, you can set an instance variable for each individual player and create a unique board that belongs to the player:

class BingoBoardGenerator

  def initialize(args)
    #dynamically set instance vars to handle n number of players
    args.fetch(:players).each_with_index do |player,index|
      instance_variable_set("@player_#{index+1}",player)
    end
  end

  def generate_boards
    instance_variables.map do |player|
      player = instance_variable_get(instance_var)
      #you will need to implement :generate_bingo_board on player...I would suggest using memoization so you can store the player's board for later retrieval
      player.generate_bingo_board
    end
  end
end

#I have no idea what your implementation looks like...
b = BingoBoardGenerator.new(players: [Player.new("Jen"),Player.new("Phil"),Player.new("Mary"),Player.new("Bert")])

b.generate_boards  

This would allow you to better encapsulate data that may belong to individual players, including the ability to ask each Player instance for its :board.

aceofbassgreg
  • 3,837
  • 2
  • 32
  • 42