Przyznaję, że jestem trochę rubinowym nowicjuszem (teraz piszę skrypty rake). W większości języków łatwo jest znaleźć konstruktory kopii. Pół godziny poszukiwań nie znalazło go w rubinie. Chcę utworzyć kopię skrótu, aby móc ją zmodyfikować bez wpływu na oryginalne wystąpienie.
Niektóre oczekiwane metody, które nie działają zgodnie z przeznaczeniem:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
W międzyczasie skorzystałem z tego nieeleganckiego obejścia
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
Hash
przedmiotami, podana odpowiedź jest dobra. Jeśli masz do czynienia z obiektami podobnymi do Hash, które pochodzą z miejsc, nad którymi nie kontrolujesz, powinieneś rozważyć, czy chcesz, aby klasa singletonowa była powiązana z Hash, czy nie. Zobacz stackoverflow.com/questions/10183370/…Odpowiedzi:
clone
Metoda jest standardowy Ruby, wbudowany sposób zrobić płytkich kopii :Pamiętaj, że zachowanie może zostać zastąpione:
źródło
Marshal.load(Marshal.dump(h))
.Jak zauważyli inni,
clone
zrobią to. Pamiętaj, żeclone
skrót tworzy płytką kopię. To jest do powiedzenia:Dzieje się tak, że odwołania do skrótu są kopiowane, ale nie do obiektów, do których się odwołują.
Jeśli chcesz głęboką kopię, to:
deep_copy
działa dla każdego obiektu, który może być zestawiony. Większość wbudowanych typów danych (Array, Hash, String i c.) Można zestawiać.Marshalling to nazwa Ruby do serializacji . Podczas marshallingu obiekt - wraz z obiektami, do których się odnosi - jest konwertowany na szereg bajtów; bajty te są następnie wykorzystywane do utworzenia kolejnego obiektu, takiego jak oryginał.
źródło
Marshal.load(Marshal.dump(o))
głębokie kopiowanie? Naprawdę nie rozumiem, co dzieje się za kulisamih1[:a] << 'bar'
można modyfikować oryginalnego obiektu (ciąg wskazywanego przez h1 [: a]), ale jeśli było zrobićh1[:a] = "#{h1[:a]}bar"
zamiast tego, by utworzyć nowy obiekt string, a punkth1[:a]
na, że podczash2[:a]
Is wciąż wskazuje stary (niezmodyfikowany) ciąg.Jeśli używasz Railsów, możesz:
http://apidock.com/rails/Hash/deep_dup
źródło
Hash może utworzyć nowy skrót z istniejącego skrótu:
źródło
Jestem również nowicjuszem w Ruby i napotkałem podobne problemy przy powielaniu skrótu. Użyj następujących. Nie mam pojęcia o szybkości tej metody.
źródło
Jak wspomniano w części „Zagadnienia bezpieczeństwa” dokumentacji Marszałka ,
Oto przykład, jak wykonać klonowanie przy użyciu JSON w Ruby:
źródło
Użyj
Object#clone
:(Mylące jest to, że dokumentacja
clone
mówi, żeinitialize_copy
jest to sposób na obejście tego, ale link do tej metodyHash
prowadzi doreplace
tego ...)źródło
Ponieważ standardowa metoda klonowania zachowuje stan zamrożenia, nie nadaje się do tworzenia nowych niezmiennych obiektów na podstawie oryginalnego obiektu, jeśli chciałbyś, aby nowe obiekty różniły się nieco od oryginału (jeśli lubisz programowanie bezstanowe).
źródło
Klon jest wolny. Aby wydajność prawdopodobnie zaczęła się od pustego skrótu i scalenia. Nie obejmuje przypadku zagnieżdżonych skrótów ...
źródło
Jest to szczególny przypadek, ale jeśli zaczynasz od wstępnie zdefiniowanego skrótu, który chcesz pobrać i wykonać kopię, możesz utworzyć metodę zwracającą skrót:
Szczególnym scenariuszem, który miałem, był zbiór skrótów schematu JSON, w którym niektóre skróty budowały inne. Początkowo definiowałem je jako zmienne klasowe i natrafiłem na ten problem z kopiowaniem.
źródło
możesz użyć poniżej, aby głęboko skopiować obiekty mieszania.
źródło
Ponieważ Ruby ma na to milion sposobów, oto inny sposób użycia Enumerable:
źródło
Alternatywny sposób dla Deep_Copy, który działał dla mnie.
Spowodowało to utworzenie deep_copy, ponieważ h2 jest tworzone przy użyciu reprezentacji tablicowej h1 zamiast referencji h1.
źródło