ruby 打包变量和猴子修补

ruby packing variables and monkey patching

好的,这是代码:

    class Board
      attr_reader :size
    
      def initialize n
        @grid = Array.new(n) {Array.new(n,:N)}
        @size = n * n
      end
    
      def [] position
        row, col = position
        @grid[row][col]
      end
    
      def []= position, val
        row, col = position
        @grid[row][col] = val
      end
    
      def num_ships
        @grid.flatten.count(:S)
      end
    
      def attack position
        if self[position] == :S 
            self[position] = :H 
            puts "you sunk my battleship"
            return true
        else
            self[position] = :X 
            return false
        end
      end
    
      def place_random_ships
        max_ships = @size * 0.25
    
        while self.num_ships < max_ships
            row = rand(0...@grid.length)
            col = rand(0...@grid.length)
            position = [row,col]
            self[position] = :S 
        end
      end
    
    
    
    
    end

但是,

def place_random_ships
        max_ships = @size * 0.25

        while self.num_ships < max_ships
            row = rand(0...@grid.length)
            col = rand(0...@grid.length)
            position = [row,col]
            self[position] = :S 
        end
      end

这行得通,并且按预期行事,但是当我避免打包 [row,col] 并直接添加它时,它行不通。

def place_random_ships
        max_ships = @size * 0.25

        while self.num_ships < max_ships
            row = rand(0...@grid.length)
            col = rand(0...@grid.length)
            
            self[row,col] = :S 
        end
      end

我对编程还是个新手,所以请尽量把问题解释到我能理解的地方,或者告诉我问题所在,这样我就可以google更好地理解它。

问题是您将 []= 定义为采用 2 个参数、数组和一个值。

def []= position, val
    row, col = position
    @grid[row][col] = val
end

对于当前的实现,您需要这样调用它

foo[[row,col]] = :S

您可能需要像这样定义 []=:

def []= row, col, val
  @grid[row][col] = val
end

然后当你想传递数组位置时你可以使用数组展开运算符。通过此实现,这两个调用都将起作用。

position = [1,2]

foo[1,2] = :S 
foo[*position] = :S

如果这样做,您可能希望以相同的方式定义 []。

def [] row,col
  @grid[row][col]
end