본문 바로가기
Web development/Ruby

[Ruby] clone, dup, deep_dup

by 자몬다 2019. 6. 18.

공통점 : 객체를 복사한다.

 

clone vs dup 비교

  • clone : 원본은 변경하지 않는다.
    싱글톤 클래스를 복사한다. frozen/tainted 상태를 보존한다. dup은 그렇지 않음.
  • dup : 객체의 attributes(내부 상태)는 복사하지 않고 새로운 인스턴스를 반환받는다.
  • dup은 객체를 복사하면 id가 없는 상태로 생성되기 때문에, 기존 객체를 복사해서 새로운 객체로 DB에 저장가능. clone은 id도 복사하기 때문에 똑같이 save했을때 덮어쓰기가 됨.

 

clone/dup vs deep_dup 비교

  • clone/dup은 내부객체는 복사되지 않았으므로 같은것을 가리킴.(shallow copy) deep_dup은 내부객체도 아예 다름.(deep copy)
deep_dup 메소드는 주어진 객체의 '깊은 복사'를 돌려줍니다. 
루비는 일반적으로 다른 객체를 포함하는 객체를 dup하더라도 내부에 있는 다른 객체들을 복사하지 않습니다. 
이러한 사본은 '앝은 복사(shallow copy)'라고 불립니다. 
예를 들자면, 아래와 같은 문자열을 포함하는 배열이 있다고 가정합시다.

array     = ['string']
duplicate = array.dup
 
duplicate.push 'another-string'
 
# 이 객체는 복사되었으므로, 복사 된쪽에만 객체가 추가됨
array     # => ['string']
duplicate # => ['string', 'another-string']
 
duplicate.first.gsub!('string', 'foo')
 
# 첫번째 요소는 복사되지 않았으므로 한쪽을 변경하면, 양쪽 배열에 모두 변경사항이 반영됨
array     # => ['foo']
duplicate # => ['foo', 'another-string']
위에서 보듯, Array 인스턴스를 복사하여 다른 객체가 생성되었으므로, 
한쪽을 변경하더라도 다른쪽은 변경되지 않게 되었습니다. 
단, 배열은 복사되었습니다만, 배열 내의 요소들은 그렇지 않습니다. 
dup 메소드는 깊은 복사를 해주지 않으므로, 배열의 내부에 있는 문자열은 복사 후에도 같은 객체입니다.

객체를 깊은 복사해야할 필요가 있는 경우에는 deep_dup를 사용해주세요.

array     = ['string']
duplicate = array.deep_dup
 
duplicate.first.gsub!('string', 'foo')
 
array     # => ['string']
duplicate # => ['foo']

http://sachinchoudhary.blogspot.com/2014/01/ruby-clone-dup-vs-rails-deepdup.html

 

흠..

솔직히 clone은 어떨때 사용할지 용도를 잘 모르겠음.

dup은 기존 객체를 복사해서 새로운 객체를 생성할때 쓰면 될듯.

deep_dup은 내용물이 같은 아예 다른 새로운 객체를 생성하는 것. deep_dup이 내가 생각하는 복사와 가장 비슷하게 동작하는 것 같음.

댓글