繁体   English   中英

使用克隆方法使用超级类而非宝石来制作红宝石对象的深层副本

[英]Making deep copy's of ruby objects using clone method using super class not a gem

我有红宝石类,我正在尝试实现克隆方法。 我希望能够使用所有类都可以继承的通用克隆方法。 类的属性可以是数组类型,哈希或其他一些对象。

我可以使它更通用,以便深度克隆吗? 可能在超类QueryModel中定义一个克隆方法? 那将如何工作?

class Bool < QueryModel

  attr_accessor :name, :should, :must, :must_not

  def clone
    Bool.new(self.name, self.should.clone, self.must.clone, self.must_not.clone) 
  end


  def serialize
      result_hash = {}
      query_hash = {}

      if( instance_variable_defined?(:@should) )
      query_hash[:should] = @should.serialize
      end

      if( instance_variable_defined?(:@must) )
        query_hash[:must] = @must.serialize
      end

      if( instance_variable_defined?(:@must_not) )
        query_hash[:must_not] = @must_not.serialize
      end

      if( instance_variable_defined?(:@should) || instance_variable_defined?(:@must) || instance_variable_defined?(:@must_not) )
        return result_hash = query_hash
    end
  end
end

这是可能使用克隆的地方:

class Query < QueryModel

  attr_accessor :query_string, :query, :bool

  def serialize 
    result_hash = {}
    query_hash = {}

    if( instance_variable_defined?(:@query_string) )
      query_hash[:query_string] = @query_string.serialize
      #result_hash[:query] = query_hash
    end

    if( instance_variable_defined?(:@query) )
      query_hash[:query] = @query
    end

    if( !instance_variable_defined?(@bool) )
      if( instance_variable_defined?(:@query) || instance_variable_defined?(:@query_string) )
        result_hash[:query] = query_hash
        return result_hash
      end
    else
      bool =  @bool.clone
      result_hash[:query] = bool
    end

  end

end

如果您不害怕新的宝石,那么变形虫宝石拥有克隆AR对象所需的一切。 如果您真的只想复制对象属性而不是关系,那么dup方法就是您想要的。

更新:对不起,昨天很晚,我以为您以某种方式使用了ActiveRecord。 对于纯红宝石解决方案,只需使用不带覆盖的Object#clone方法,并指定指定Object#clone的行为,如下所示:

class Bool
  def initialize_copy(original)
    super # this already clones instance vars that are not objects

    # your custom strategy for 
    # referenced objects can be here

  end
end

这是文档对此的评价。

如果您使用创新/原型设计模式解决问题,则可以像下面的示例一样进行操作-

class ConcretePrototype
  def copy
  prototype = clone

    instance_variables.each do |ivar_name|
      prototype.instance_variable_set( ivar_name,
      instance_variable_get(ivar_name).clone)
    end

    prototype
  end
end

class Application
  def run
    concreate_prototype = ConcretePrototype.new
    concreate_prototype_2 = concreate_prototype.copy
    puts concreate_prototype.inspect
    puts concreate_prototype_2.inspect
  end
end

这样,您可以在没有任何宝石的情况下深克隆对象。 参考-https://github.com/vatrai/design_patterns/blob/master/creational/prototype.rb

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM