Saya akan mengakui bahwa saya sedikit pemula yang ruby (menulis skrip menyapu, sekarang). Dalam sebagian besar bahasa, copy constructor mudah ditemukan. Setengah jam pencarian tidak menemukannya di ruby. Saya ingin membuat salinan hash sehingga saya dapat memodifikasinya tanpa memengaruhi instance asli.
Beberapa metode yang diharapkan yang tidak berfungsi sebagaimana dimaksud:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
Sementara itu, saya telah menggunakan solusi yang salah ini
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
Hash
objek biasa , jawaban yang diberikan baik. Jika Anda berurusan dengan objek mirip Hash yang berasal dari tempat yang tidak Anda kontrol, Anda harus mempertimbangkan apakah Anda ingin kelas tunggal yang terkait dengan Hash digandakan atau tidak. Lihat stackoverflow.com/questions/10183370/...Jawaban:
The
clone
Metode standar Ruby, built-in cara untuk melakukan dangkal-copy :Perhatikan bahwa perilaku mungkin diganti:
sumber
Marshal.load(Marshal.dump(h))
.Seperti yang telah ditunjukkan orang lain,
clone
akan melakukannya. Ketahuilah bahwaclone
hash membuat salinan yang dangkal. Artinya:Apa yang terjadi adalah bahwa referensi hash sedang disalin, tetapi bukan objek yang merujuk referensi.
Jika Anda ingin salinan yang dalam, maka:
deep_copy
bekerja untuk objek apa pun yang dapat disusun. Sebagian besar tipe data bawaan (Array, Hash, String, & c.) Dapat disusun.Marshalling adalah nama Ruby untuk serialisasi . Dengan marshalling, objek - dengan objek yang dirujuk - dikonversi ke serangkaian byte; byte tersebut kemudian digunakan untuk membuat objek lain seperti aslinya.
sumber
Marshal.load(Marshal.dump(o))
penyalinan yang dalam? Saya benar-benar tidak mengerti apa yang terjadi di balik layarh1[:a] << 'bar'
mengubah objek asli (string ditunjukkan oleh h1 [: a]) tetapi jika Anda harus melakukannyah1[:a] = "#{h1[:a]}bar"
, Anda akan membuat objek string baru, dan arahkanh1[:a]
ke sana, sementara ituh2[:a]
adalah masih menunjuk ke string lama (tidak dimodifikasi).Jika Anda menggunakan Rails, Anda dapat melakukannya:
http://apidock.com/rails/Hash/deep_dup
sumber
Hash dapat membuat hash baru dari hash yang ada:
sumber
Saya juga seorang pemula untuk Ruby dan saya menghadapi masalah serupa dalam menduplikasi hash. Gunakan yang berikut ini. Saya tidak tahu tentang kecepatan metode ini.
sumber
Seperti disebutkan di bagian Pertimbangan Keamanan dari dokumentasi Marshal ,
Berikut adalah contoh cara melakukan kloning menggunakan JSON di Ruby:
sumber
Gunakan
Object#clone
:(Yang membingungkan, dokumentasi untuk
clone
mengatakan ituinitialize_copy
adalah cara untuk menimpanya, tetapi tautan untuk metode ituHash
mengarahkan Anda untukreplace
sebaliknya ...)sumber
Karena metode kloning standar mempertahankan keadaan beku, itu tidak cocok untuk membuat objek baru yang tidak dapat diubah berdasarkan objek asli, jika Anda ingin objek baru sedikit berbeda dari yang asli (jika Anda suka pemrograman stateless).
sumber
Klon lambat. Untuk kinerja mungkin harus dimulai dengan hash dan penggabungan kosong. Tidak mencakup kasus hash bersarang ...
sumber
Ini adalah kasus khusus, tetapi jika Anda mulai dengan hash yang telah ditentukan yang ingin Anda ambil dan buat salinannya, Anda bisa membuat metode yang mengembalikan hash:
Skenario khusus yang saya miliki adalah saya memiliki koleksi hash-skema JSON di mana beberapa hash dibangun dari yang lain. Saya awalnya mendefinisikan mereka sebagai variabel kelas dan mengalami masalah salinan ini.
sumber
Anda dapat menggunakan di bawah ini untuk menyalin objek Hash.
sumber
Karena Ruby memiliki sejuta cara untuk melakukannya, inilah cara lain menggunakan Enumerable:
sumber
Cara alternatif untuk Deep_Copy yang bekerja untuk saya.
Ini menghasilkan deep_copy karena h2 dibentuk menggunakan representasi array dari referensi h1 daripada h1.
sumber