复制一个类,以便在Ruby中修改新类时不会修改旧类

复制一个类,以便在Ruby中修改新类时不会修改旧类,ruby,oop,functional-programming,Ruby,Oop,Functional Programming,我有一个ConnectFour类,我有一个方法: def apply_move!(column_number, symbol, row_number = 0) # Some gravity logic @board[row_number][column_number] = symbol end 这将在适当的位置修改类 我试着在它周围写一个包装器,它返回一个电路板,并且不改变原来的电路板,这样就可以使用函数编程技术 我的尝试是: def apply_move(column_number,

我有一个
ConnectFour
类,我有一个方法:

def apply_move!(column_number, symbol, row_number = 0)
  # Some gravity logic
  @board[row_number][column_number] = symbol
end
这将在适当的位置修改类

我试着在它周围写一个包装器,它返回一个电路板,并且不改变原来的电路板,这样就可以使用函数编程技术

我的尝试是:

def apply_move(column_number, symbol)
  dummy = ConnectFour.new(@board)
  dummy.apply_move!(column_number, symbol)
  dummy
end
但问题是修改
dummy
也会修改原始类本身!如何仅修改
dummy
dummy

更多代码和上下文

您可能对以下内容感兴趣:

class CpuWinIfPossible < Player
  def decide_move(board)
    (0...6).find do |move|
      board.apply_move(move, self.symbol).is_won?(self.symbol)
    end || (0...6).to_a.sample
  end
end
构造函数

class ConnectFour
  attr_accessor :board


  def initialize(board)
    @board = board
  end

您可以制作该类的深度副本:

new_class = Marshal.load(Marshal.dump(ConnectFour))

然后从那里开始(
dummy=new#class.new(@board)

我认为这与@board的当前状态有关,如果您将
ConnectFour#initialize
更改为如下所示,我认为应该可以工作

def initialize(board)
  @board = board.dup
end
如果您使用的是rails,则可以使用
deep\u dup

def initialize(board)
  @board = board.deep_dup
end

解决我的问题的方法是:

def initialize(board)
  @board = board.map(&:dup)
end

但是正如@JörgWMittag所指出的,我应该让我的代码更加面向对象,以适应Ruby风格,这样的解决方案就不再需要了。

我不明白您展示的任何方法是如何可以想象地改变类的。你一定还有别的事没告诉我们。还有,你说的“旧阶级”和“新阶级”是什么意思?我在这里只能看到一个类,
ConnectFour
@JörgWMittag添加了一个重要的方法,可能我的术语并不像我说的类那样精确,我真正的意思是一个包含类的特定实例的变量。请分享
ConnectFour
的构造函数方法?我很确定这是个问题,不要发送
@board
,而是发送
@board.clone
@board.dup
@Aguardientico补充道,感谢您的努力,即使我的问题不完整:谢谢,所以问题是,
@board
实际上是由所有COnnectFour实例共享的?等一下,我想我还是有问题的,非常感谢你,无论如何这只会复制
@board
数组,而不是
@board
数组中包含的数组。真正的问题是Ruby是一种面向对象的语言,而不是一种面向整数数组的语言,所以你应该为你的电路板使用一个
Board
对象,而不是一个整数数组。@JörgWMittag我知道这个问题比看起来的更严重,Ruby显示的缺乏支持源于我对OOT的不遵从性。看起来rails有一个
deep\u dup
方法来更新answer@admdrew我在用第二人称对自己说话,以使这篇文章将来更具可读性visitors@admdrew现在是第一人称。
def initialize(board)
  @board = board.map(&:dup)
end