代码之家  ›  专栏  ›  技术社区  ›  Andy

如何在Ruby中为对象的深度复制/克隆创建操作符?

  •  1
  • Andy  · 技术社区  · 14 年前

    := )

    a := b = {}
    b[1] = 2
    p a # => {}
    p b # => {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
    p a # => {}
    p b # => {1=>2}
    
    2 回复  |  直到 14 年前
        1
  •  2
  •   Justin L.    14 年前

    首先,superators的语法是

    superator ":=" do |operand|
      #code
    end
    

    第二,你和他们有关系 Marshal ……但这有点神奇。只要你清楚自己在做什么,就可以随意使用它。

    self

    另外,在你的例子中, a 必须先存在并定义,然后才能调用该方法 :=

    你最好的选择可能是:

    class Object
      def deep_clone
        Marshal::load(Marshal.dump(self))
      end
    end
    

    a = (b = {}).deep_clone
    b[1] = 2
    p a # => {}
    p b # => {1=>2}
    
        2
  •  3
  •   Joshua Cheek    14 年前

    哇,超级巨星看起来真漂亮!但不幸的是,这对你不起作用,有两个原因。首先,运算符与regex不匹配(不能使用冒号)。很简单,找个新接线员。但我认为第二个问题是无法克服的,superator基本上是在左边的对象上定义的方法名。所以你不能把它用于赋值语句。如果未定义变量,则无法使用它,这将引发错误。如果它被定义了,那么你就不能以任何对我来说很明显的方式改变它的类型(也许有某种程度的反射和元编程,这远远超出了我所知道的任何东西,但事实上似乎不太可能。。。当然,我从来没有想过有可能创造出超级巨星,所以谁知道呢)。

    所以我想你又开始破解parse.y并重建你的Ruby了。