我正在写一个简单的Tic Tac Toe游戏,其中我有一个用于棋盘,玩家,计算机和游戏本身的课程.在我的Board类中,我将类变量@board(它是一个数组)设置为attr_reader,它应该禁止直接写入它.虽然以下方法不起作用(按预期)
game_board = Board.new game_board.board = "some junk"
以下工作,我不想发生
game_board = Board.new game_board.board[0] = "some junk"
如何停止将类数组变量@board写入?目前的类代码如下:
class Board attr_reader :board def initialize create_board end private def create_board @board = Array.new(3).map{Array.new(3)} end end game_board = Board.new game_board.board #=> [[nil,nil,nil],[nil,nil]] game_board.board = "junk" #=> undefined method 'board =' game_board.board[0] = "junk" game_board.board #=> ["junk",nil]] #I don't want to allow this!
解决方法
我相信你需要使数组不可变.
您可以使用Array#freeze来实现这一目标.
之后你的代码应如下所示:
class Board attr_reader :board def initialize create_board end private def create_board @board = Array.new(3).map{Array.new(3).freeze}.freeze end end
在运行您的第一个示例时:
>> game_board = Board.new #<Board:0x00000001648b50 @board=[[nil,nil]]> >> game_board.board = "some junk" NoMethodError: undefined method `board=' for #<Board:0x00000001648b50> from (irb):14 from /home/alfie/.rvm/rubies/ruby-2.1.3/bin/irb:11:in `<main>'
在运行第二个示例时:
>> game_board = Board.new #<Board:0x00000001639e48 @board=[[nil,nil]]> >> game_board.board[0] = "some junk" RuntimeError: can't modify frozen Array from (irb):16 from /home/alfie/.rvm/rubies/ruby-2.1.3/bin/irb:11:in `<main>'