복붙노트

[RUBY-ON-RAILS] 어떻게 루비에서 객체의 전체 복사본을 만드는 방법?

RUBY-ON-RAILS

어떻게 루비에서 객체의 전체 복사본을 만드는 방법?

좀 검색이 깊은 복사 연산자를 만드는 방법에 대한 몇 가지 다른 방법과 게시물을 발견했다.

빠른 거기에 쉽게 (내장) 방식 루비 깊은 복사 객체에? 필드는 배열이나 해시 수 없습니다.

루비 1.9.2에서 작업.

해결법

  1. ==============================

    1.깊은 사본은 바닐라 루비에 내장되지 않은,하지만 당신은 마샬링 및 객체를 비 정렬 화해를 해킹 할 수 :

    깊은 사본은 바닐라 루비에 내장되지 않은,하지만 당신은 마샬링 및 객체를 비 정렬 화해를 해킹 할 수 :

    Marshal.load(Marshal.dump(@object))
    

    이 완벽한 것은 아니지만, 모든 개체에 대해 작동하지 않습니다. 보다 강력한 방법

    class Object
      def deep_clone
        return @deep_cloning_obj if @deep_cloning
        @deep_cloning_obj = clone
        @deep_cloning_obj.instance_variables.each do |var|
          val = @deep_cloning_obj.instance_variable_get(var)
          begin
            @deep_cloning = true
            val = val.deep_clone
          rescue TypeError
            next
          ensure
            @deep_cloning = false
          end
          @deep_cloning_obj.instance_variable_set(var, val)
        end
        deep_cloning_obj = @deep_cloning_obj
        @deep_cloning_obj = nil
        deep_cloning_obj
      end
    end

    출처:

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/43424

  2. ==============================

    2.나는 루비 객체의 깊은 클론을 수행하는 기본 구현을 만들었습니다.

    나는 루비 객체의 깊은 클론을 수행하는 기본 구현을 만들었습니다.

    약 6-7 배 빠른 원수 방식에 비해입니다.

    https://github.com/balmma/ruby-deepclone

    이 프로젝트가 더 이상 유지되지 않는다는 것을 주 (지난 2017 년,이보고 된 문제를 커밋)

  3. ==============================

    3.레일은 그 DUP와 클론의 반대로 개체의 전체 복사본을 반환 할 것이다 deep_dup라는 이름의 재귀 적 방법을 가지고, 심지어 복합 객체 (배열 / 해시의 배열 / 해시)에서 작동합니다. 그것은 쉽게 다음과 같음있다 :

    레일은 그 DUP와 클론의 반대로 개체의 전체 복사본을 반환 할 것이다 deep_dup라는 이름의 재귀 적 방법을 가지고, 심지어 복합 객체 (배열 / 해시의 배열 / 해시)에서 작동합니다. 그것은 쉽게 다음과 같음있다 :

    def deep_dup
      map { |it| it.deep_dup }
    end
    
  4. ==============================

    4.루비 객체의 깊은 클론을 수행하는 기본 구현이 있습니다 : ruby_deep_clone은

    루비 객체의 깊은 클론을 수행하는 기본 구현이 있습니다 : ruby_deep_clone은

    보석으로 설치 :

    gem install ruby_deep_clone
    

    사용 예제 :

    require "deep_clone"
    object = SomeComplexClass.new()
    cloned_object = DeepClone.clone(object)
    

    약 6 ~ 7 배 빠른 원수 방식에 비해이고 이벤트는 냉동 객체와 함께 작동합니다.

    이 프로젝트가 더 이상 유지되지 않는다는 것을 주 (지난 2017 년,이보고 된 문제를 커밋)

  5. ==============================

    5.이 중복 된 보석을 사용할 수 있습니다.

    이 중복 된 보석을 사용할 수 있습니다.

    그것은 반복적으로 중복 객체에 해당 할 수있는 작은 순수 루비 보석입니다 그것은 새로운 중복 너무 그것의 객체 참조를 복제합니다.

    require 'duplicate'
    duplicate('target object')
    

    https://rubygems.org/gems/duplicate

    https://github.com/adamluzsi/duplicate.rb

  6. ==============================

    6.나는 당신이 당신의 기본 루비 코어, 단지 깊은 복제 방법에 설탕을 많이 추가하는 ActiveSupport 보석을 사용하는 것이 좋습니다 것입니다.

    나는 당신이 당신의 기본 루비 코어, 단지 깊은 복제 방법에 설탕을 많이 추가하는 ActiveSupport 보석을 사용하는 것이 좋습니다 것입니다.

    당신은 추가 된 방법에 대한 자세한 내용은 문서로 볼 수있다.

  7. ==============================

    7.자동 깊은 클론은 당신이 원하는 것을 항상 아닙니다. 종종 당신은 깊은 복제에 선택된 몇 가지 속성을 정의 할 필요가있다. 이 작업을 수행하는 유연한 방법은 initialize_copy, initialize_dup 및 initialize_clone 방법을 구현하는 것입니다.

    자동 깊은 클론은 당신이 원하는 것을 항상 아닙니다. 종종 당신은 깊은 복제에 선택된 몇 가지 속성을 정의 할 필요가있다. 이 작업을 수행하는 유연한 방법은 initialize_copy, initialize_dup 및 initialize_clone 방법을 구현하는 것입니다.

    당신은 클래스가있는 경우 :

    class Foo
      attr_accessor :a, :b
    end
    

    당신은 단지 깊은 복제 할 : B, 당신은 initialize_ * 메소드를 오버라이드 (override) :

    class Foo
      attr_accessor :a, :b
    
      def initialize_dup(source)
        @b = @b.dup
        super
      end
    end
    

    물론 당신은 자신의 속성 중 일부는, 당신은 B의 클래스에서 동일한 작업을 수행 또한 깊은 복제에 @b합니다.

    레일이 (https://github.com/rails/rails/blob/0951306ca5edbaec10edf3440d5ba11062a4f2e5/activemodel/lib/active_model/errors.rb#L78 참조) 않습니다

    더 자세한 설명을 위해, 나는이 게시물에서 여기를 배운 https://aaronlasseigne.com/2014/07/20/know-ruby-clone-and-dup/

  8. ==============================

    8.또한 deep_dive 확인하십시오. 이것은 당신이 당신의 객체 그래프의 전체 복사본을 제어 할 수 있습니다.

    또한 deep_dive 확인하십시오. 이것은 당신이 당신의 객체 그래프의 전체 복사본을 제어 할 수 있습니다.

    https://rubygems.org/gems/deep_dive

  9. ==============================

    9.당신은 정말이에 대한 보석이 필요하지 않습니다. 이것은 보석의 오버 헤드 가치가하지 않은, 이것보다 훨씬 더 간단 수 없습니다!

    당신은 정말이에 대한 보석이 필요하지 않습니다. 이것은 보석의 오버 헤드 가치가하지 않은, 이것보다 훨씬 더 간단 수 없습니다!

    def deep_clone(obj)
      obj.clone.tap do |new_obj|
        new_obj.each do |key, val|
          new_obj[key] = deep_clone(val) if val.is_a?(Hash)
        end
      end
    end
    
  10. from https://stackoverflow.com/questions/8206523/how-to-create-a-deep-copy-of-an-object-in-ruby by cc-by-sa and MIT license