如何在Ruby中创建副本构造函数

时间:2018-12-15 20:59:49

标签: ruby oop constructor copy copy-constructor

我是Ruby的新手,正在编写一个游戏,其中有一个名为Player的类,并且在尝试复制对象时遇到问题。我的代码如下所示:

class Player

    attr_accessor :imprisoned
    attr_reader :name
    attr_reader :balance
    attr_accessor :freedom_card
    attr_accessor :current_box
    attr_reader :properties

    # Default constructor with no parameters
    def initialize (name = "")
        @name = name
        @imprisoned = false
        @balance = 7500
        @properties = Array.new
        @freedom_card = nil
        @current_box = nil
    end

    # Constructor with one parameter (it works)
    def self.nuevo (name)
        self.new(name)
    end

    # Copy constructor (doesn't seem to work)
    def self.copia (other_player)
        @name = other_player.name
        @imprisoned = other_player.imprisoned
        @balance = other_player.balance
        @properties = other_player.properties
        @freedom_card = other_player.freedom_card
        @current_box = other_player.current_box
        self
    end

    # ...
end

在对此进行测试时:

player = Player.nuevo ("John")
puts player.name
player_2 = Player.copia(player)
puts player_2.name

我明白了:

John
NoMethodError: undefined method `name' for ModeloQytetet::Player:Class

可能是什么错误?当使用复制对象中的其他属性或方法时,它也将失败,但是所有属性或方法在原始对象中都可以正常工作。在此先感谢您,并感谢您遇到任何英语错误(不是我的母语)。

1 个答案:

答案 0 :(得分:1)

在:

def self.copia(other_player)
  @name = other_player.name
  @imprisoned = other_player.imprisoned
  @balance = other_player.balance
  @properties = other_player.properties
  @freedom_card = other_player.freedom_card
  @current_box = other_player.current_box
  self
end

@ Player的实例变量相关。您实际上什么也没做,只需设置一些变量并返回self,这是一个,而不是实例

您可以使用

def self.copia(other_player)
  player = new(other_player.name)
  player.from(other_player)
  player
end

def from(other_player)
  @name = other_player.name
  @imprisoned = other_player.imprisoned
  @balance = other_player.balance
  @properties = other_player.properties
  @freedom_card = other_player.freedom_card
  @current_box = other_player.current_box
end