나는 내가 약간의 루비 초보자임을 인정할 것입니다 (지금 레이크 스크립트 작성). 대부분의 언어에서 복사 생성자를 쉽게 찾을 수 있습니다. 30 분 동안 검색하면 루비에서 찾지 못했습니다. 원본 인스턴스에 영향을 미치지 않고 해시 복사본을 만들려고합니다.
의도 한대로 작동하지 않는 일부 예상되는 방법 :
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
그 동안 나는이 우아한 해결 방법에 의지했습니다.
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
답변
이 clone
방법은 얕은 복사 를 수행하는 Ruby의 표준 내장 방법입니다 .
irb(main):003:0> h0 = {"John" => "Adams", "Thomas" => "Jefferson"}
=> {"John"=>"Adams", "Thomas"=>"Jefferson"}
irb(main):004:0> h1 = h0.clone
=> {"John"=>"Adams", "Thomas"=>"Jefferson"}
irb(main):005:0> h1["John"] = "Smith"
=> "Smith"
irb(main):006:0> h1
=> {"John"=>"Smith", "Thomas"=>"Jefferson"}
irb(main):007:0> h0
=> {"John"=>"Adams", "Thomas"=>"Jefferson"}
동작이 재정의 될 수 있습니다.
이 메서드에는 클래스 별 동작이있을 수 있습니다. 그렇다면, 그 행동은
#initialize_copy
클래스 의 방법 으로 문서화 될 것 입니다.
답변
다른 사람들이 지적했듯이 clone
그렇게 할 것입니다. 주의하십시오 clone
해시의 얕은 복사본을 만듭니다. 즉 말하자면:
h1 = {:a => 'foo'}
h2 = h1.clone
h1[:a] << 'bar'
p h2 # => {:a=>"foobar"}
일어나는 일은 해시의 참조가 복사되고 있지만 참조가 참조하는 객체는 아닙니다.
깊은 사본을 원한다면 다음을 수행하십시오.
def deep_copy(o)
Marshal.load(Marshal.dump(o))
end
h1 = {:a => 'foo'}
h2 = deep_copy(h1)
h1[:a] << 'bar'
p h2 # => {:a=>"foo"}
deep_copy
마샬링 될 수있는 모든 개체에 적용됩니다. 대부분의 기본 제공 데이터 형식 (Array, Hash, String 등)을 마샬링 할 수 있습니다.
Marshalling 은 루비의 직렬화 이름입니다 . 마샬링을 사용하면 객체가 참조하는 객체가 일련의 바이트로 변환됩니다. 그런 다음 해당 바이트는 원본과 같은 다른 객체를 만드는 데 사용됩니다.
답변
답변
해시는 기존 해시에서 새 해시를 만들 수 있습니다.
irb(main):009:0> h1 = {1 => 2}
=> {1=>2}
irb(main):010:0> h2 = Hash[h1]
=> {1=>2}
irb(main):011:0> h1.object_id
=> 2150233660
irb(main):012:0> h2.object_id
=> 2150205060
답변
나는 또한 Ruby의 초보자이며 해시 복제와 비슷한 문제에 직면했습니다. 다음을 사용하십시오. 나는이 방법의 속도에 대해 전혀 모른다.
copy_of_original_hash = Hash.new.merge(original_hash)
답변
에서 언급 한 바와 같이 원수 문서의 보안 고려 사항 섹션 ,
신뢰할 수없는 데이터를 역 직렬화해야하는 경우 JSON 또는 String, Array, Hash 등과 같은 단순한 ‘기본’유형 만로드 할 수있는 다른 직렬화 형식을 사용하십시오.
다음은 Ruby에서 JSON을 사용하여 복제하는 방법에 대한 예입니다.
require "json"
original = {"John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
cloned = JSON.parse(JSON.generate(original))
# Modify original hash
original["John"] << ' Sandler'
p original
#=> {"John"=>"Adams Sandler", "Thomas"=>"Jefferson", "Johny"=>"Appleseed"}
# cloned remains intact as it was deep copied
p cloned
#=> {"John"=>"Adams", "Thomas"=>"Jefferson", "Johny"=>"Appleseed"}
답변
사용 Object#clone
:
h1 = h0.clone
(혼란스럽게도에 대한 문서 clone
는 initialize_copy
이것을 무시하는 방법 이라고 말하지만 그 방법에 대한 링크는 대신에 Hash
당신을 지시합니다 replace
…)