我可以覆盖赋值运算符的行为吗?

时间:2013-07-13 23:44:07

标签: ruby

我的游戏开发框架有一个Point类(存储xy坐标和其他有用的东西)。我的游戏对象具有@position属性,即Point个实例。修改@position后,游戏对象将被绘制到其他地方。

我的问题是:

@someSprite.position = Point.new(100,100)
temp = @someSprite.position
temp.x = 500

temp成为@someSprite.position的引用。修改它也会改变精灵的位置。这是我不想要的。我希望temp成为另一个实例。

我做不到这样的事情:

temp = @someSprite.position.clone

由于框架中的另一个细节:Pointobservable@someSprite正在观察自己的属性@someSprite.position

如果我使用clone,那么temp也会克隆观察者注册表。当temp的状态发生变化时,@someSprite会被通知,造成混乱。

然后就可以做到这一点:

temp = @someSprite.position.clone
temp.remove_observer(@someSprite)

但这感觉不切实际和黑客。

另一种方法是:

temp = Point.new(@someSprite.position)

我为Point创建一个构造函数,它从另一个Point获取值(不复制观察者注册表)。这听起来像目前为止最好的方法,但我想要实现的是

temp = @someSprite.position

可以这样做吗?在这种情况下,我可以覆盖赋值运算符的行为吗?

3 个答案:

答案 0 :(得分:1)

您解释了无法使用clone的原因,但这并不意味着您无法覆盖clone或创建duplicate等新方法。

所以在你的Point类上只需定义:

def duplicate
  Point.new(x,y)
end

然后你可以这样做:

temp = @someSprite.position.duplicate

答案 1 :(得分:1)

我假设你在attr_reader上使用@position来定义精灵的position方法。但您也可以定义自己的getter。在这种情况下,我建议你为该职位创建一个明确的getter:

class Sprite
    def position
        return Point.new(@position.x, @position.y)
    end
end

你想要在对象内部引用精灵的位置而不是它的值的副本是非常罕见的;暴露一个班级的私人成员实际上是非常危险的。

答案 2 :(得分:0)

Ruby是开源的,所以当然,您可以使用语言C覆盖一些知识操作。但我不建议。