如何正确地从另一个内部类访问一个内部类中的实例变量?

时间:2019-01-12 22:53:25

标签: ruby inner-classes

我正在创建一个井字游戏。我是红宝石的新手,并且定义了一个类Game,其中有两个内部类PlayerGameBoard。在Game中,我定义了两个实例变量player1player2。我试图像这样在方法player1中访问player2GameBoard.update_gameboard

def update_gameboard(player)
      move = if player == 1
               @player1.moves[@player1.turn]
             else
               @player2.moves[@player2.turn]
             end
.
.
.

我得到了错误:

/Users/Jacob/Development/RubyDev/RubymineProjects/TicTacToe/tictactoe.rb:85:in `update_gameboard': undefined method `moves' for nil:NilClass (NoMethodError)
    from /Users/Jacob/Development/RubyDev/RubymineProjects/TicTacToe/tictactoe.rb:44:in `play'
    from /Users/Jacob/Development/RubyDev/RubymineProjects/TicTacTOe/main.rb:30:in `<top (required)>'
    from -e:1:in `load'
    from -e:1:in `<main>'

Process finished with exit code 1

moves不是方法,它是一个数组。 (playGame中的一种调用update_gameboard的方法)

如何从内部类(例如Game)访问外部类(GameBoard)的实例变量?

class Game
  attr_accessor :winner, :player1, :player2, :gameboard

  def initialize(player1_name, player2_name)
    @player1 = Player.new(player1_name, 'X')
    @player2 = Player.new(player2_name, 'O')
    @gameboard = GameBoard.new
  end
.
.
.
  class GameBoard
    attr_accessor :current_gameboard
    attr_reader :gameboard_move_map

    def initialize
          # initialize irrelevant GameBoard variables
    end

    def update_gameboard(player)
      move = if player == 1
               @player1.moves[@player1.turn]
             else
               @player2.moves[@player2.turn]
             end
      #then some more stuff that uses @player1 and @player2
    end
.
.
.
  end
end



1 个答案:

答案 0 :(得分:3)

这里非常重要的概念。 “内部阶级”并没有按照您的想法去做。除了命名空间,这两个类之间绝对没有任何关系或特殊行为。基本上,就像对待内部类一样,完全将其定义为完全独立,因为这就是它的行为。

但是,您可以做的一件事就是将GameBoard实例的引用传递给Game构造函数,以便您可以访问实例变量:

(请注意,我仅显示与答案相关的部分,并且为了简洁起见,省略了代码的其他部分):

class GameBoard
  attr_reader :game
  def initialize(game)
    @game = game
  end
end

class Game
  def initialize(player1_name, player2_name)
    @player1 = Player.new(player1_name, 'X')
    @player2 = Player.new(player2_name, 'O')

    # Note I pass the Game instance as self here:
    @gameboard = GameBoard.new(self)
  end
end

然后在GameBoard实例方法中,您可以执行以下操作:

game.player1.moves[game.player1.turn]

game是attr_reader生成的方法(指的是初始化中设置的@game实例变量)。

相关问题