如何在Ruby中创建用于深度复制/克隆对象的运算符?
我想通过引入一个新的运算符来实现以下目的(例如:=
)
a := b = {} b[1] = 2 pa # => {} pb # => {1=>2}
据我所知,我需要修改Object
类,但我不知道该怎么做才能得到我想要的东西。
require 'superators' class Object superator ":=" operand # update, must be: superator ":=" do |operand| # self = Marshal.load(Marshal.dump(operand)) # ??? end end
你能帮我这个吗?
更新
好吧,超级运动员可能不会帮助我,但我仍然想要这样的操作员。 我怎么能(或你)为Ruby创建一个扩展,我可以将其作为模块加载?
require 'deep_copy_operator' a !?= b = {} # I would prefer ":=" but don't really care how it is spelled b[1] = 2 pa # => {} pb # => {1=>2}
首先,superators的语法是
superator ":=" do |operand| #code end
这是一个块,因为superator是一个元编程宏。
其次,你有一些与Marshal
东西……但它有点神奇。 只要您完全了解它正在做什么,请随意使用它。
第三,你正在做的事情对于一个superator是不太可行的(我相信),因为在一个函数中不能修改self
。 (如果有人不知道,请告诉我)
此外,在您的示例中,必须首先存在并在能够调用方法之前定义:=
in。
你最好的选择可能是:
class Object def deep_clone Marshal::load(Marshal.dump(self)) end end
生成对象的深层克隆。
a = (b = {}).deep_clone b[1] = 2 pa # => {} pb # => {1=>2}
哇,superators看起来整洁! 但不幸的是,由于两个原因,这对你不起作用。 首先,您的运算符与正则表达式不匹配(您不能使用冒号)。 很容易找到一个新的运营商。 但是第二个我认为不能克服,超级运算符基本上是在左边的对象上定义的方法名称。 所以你不能将它用于赋值语句。 如果未定义您的变量,则无法使用它,这会引发错误。 如果它是定义的,那么你不能以任何对我来说显而易见的方式改变它的类型(可能有某种程度的reflection和元编程远远超出我所知道的范围,但它实际上似乎不太可能……当然,我从没想过有可能制造出超级大国,所以谁知道呢)。
所以我认为你又回到了破解parse.y并重建你的Ruby。