【问题标题】:Ruby: Nested Array behaving strangley as an Instance VariableRuby:嵌套数组表现得像实例变量一样扼杀
【发布时间】:2017-04-28 23:38:30
【问题描述】:

对于我们的任务,我们的目的是在任意大小的棋盘上创建井字游戏,并接受一个数组作为输入。我还没有完全掌握 attr_accessor 模块,而且我很确定我用错了。

class Board
  attr_accessor :grid

  def initialize(grid = nil)
    if grid.nil?
      @grid = Array.new(3, Array.new(3, nil))
    else
      @grid = grid
    end
  end

  def place_mark(pos, mark)
    @grid[pos[0]][pos[1]] = mark
  end

 end

我的主要问题是即使“place_mark”似乎应该将输入放在一个位置。我得到以下信息:

game.place_mark([0,0], :X) #=> [[:X, nil, nil], [:X, nil, nil], [:X, nil, nil]]

当我在课堂之外重新创建它时,它就像我认为的那样工作。我搞砸了什么?

【问题讨论】:

标签: ruby multidimensional-array class-instance-variables


【解决方案1】:

Board 类和attr_accessor 都没有问题。然而,网格的初始化不起作用。 @grid = Array.new(3, Array.new(3, nil)) 是罪魁祸首。第四个代码示例in the docs 显示了它应该如何完成,上面的文字解释了为什么 OP 的代码表现得像它一样。每个 Ruby 学生至少会被这个困住一次。

【讨论】:

  • 哦,谢谢你的帮助。 Ruby 这样做是为了提高效率,还是有与创建引用同一对象的嵌套数组相关的有用技巧?
  • @SeanChowdhury 按照你期望的方式来做这件事比听起来更难 - 当你没有通过一个块时,对 Array.new 的内部调用已经发生,它是 inner = Array.new(3,nil); @grid = Array.new(3,inner) 完全相同。因此,我们无法像处理块一样多次执行该代码。所以,如果我们想在每个点得到不同的对象,我们就必须复制传入的那个。我们做浅拷贝还是深拷贝?有时两者都会出错。提供非块语法只是为了方便 2 等不可变值。
  • 要详细说明浅层与深层问题,请考虑inner = [Person.new('Jane'),Person.new('Bill'),Person.new('Sally'); outer = Array.new(3,inner)。您是否希望最终结果涉及 9 个人(其中一些同名)?三个不同的列表恰好包含相同的人?还是同样的名单三次? “显而易见”的答案会因您使用的示例以及您询问的对象而异。
猜你喜欢
  • 2021-02-19
  • 2017-01-02
  • 2023-03-05
  • 1970-01-01
  • 2014-09-21
  • 2021-12-10
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
相关资源
最近更新 更多