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
.