如何从另一个内部 class 正确访问一个内部 class 中的实例变量?
How to properly access instance variables in one inner-class from another inner-class?
我正在制作一款井字游戏。我是 ruby 的新手,定义了一个 class Game
,有两个内部 classes Player
和 GameBoard
。在 Game
中,我定义了两个实例变量 player1
和 player2
。我正在尝试访问方法 GameBoard.update_gameboard
中的 player1
和 player2
,就像这样
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
不是一个方法,它是一个数组。 (play
是 Game
中调用 update_gameboard
的方法)
如何从内部class(例如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
这里的概念非常重要。 "Inner class" 并没有按照您的想法行事。除了命名空间之外,这两个 classes 之间绝对没有任何关系或特殊行为。基本上,只需将内部 class 视为完全单独定义的,因为这就是它的行为方式。
不过,您可以做的一件事是向 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生成的方法(指initialize中设置的@game
实例变量)
我正在制作一款井字游戏。我是 ruby 的新手,定义了一个 class Game
,有两个内部 classes Player
和 GameBoard
。在 Game
中,我定义了两个实例变量 player1
和 player2
。我正在尝试访问方法 GameBoard.update_gameboard
中的 player1
和 player2
,就像这样
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
不是一个方法,它是一个数组。 (play
是 Game
中调用 update_gameboard
的方法)
如何从内部class(例如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
这里的概念非常重要。 "Inner class" 并没有按照您的想法行事。除了命名空间之外,这两个 classes 之间绝对没有任何关系或特殊行为。基本上,只需将内部 class 视为完全单独定义的,因为这就是它的行为方式。
不过,您可以做的一件事是向 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生成的方法(指initialize中设置的@game
实例变量)