J'admets que je suis un peu un débutant rubis (écrit des scripts de râteau, maintenant). Dans la plupart des langues, les constructeurs de copie sont faciles à trouver. Une demi-heure de recherche ne l'a pas trouvée en rubis. Je souhaite créer une copie du hachage afin de pouvoir le modifier sans affecter l'instance d'origine.
Quelques méthodes attendues qui ne fonctionnent pas comme prévu:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
En attendant, j'ai eu recours à cette solution de contournement inélégante
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
Hash
objets simples , la réponse fournie est bonne. Si vous traitez avec des objets de type Hash provenant d'endroits que vous ne contrôlez pas, vous devez déterminer si vous souhaitez que la classe singleton associée au Hash soit dupliquée ou non. Voir stackoverflow.com/questions/10183370/…Réponses:
La
clone
méthode est la méthode standard et intégrée de Ruby pour effectuer une copie superficielle :Notez que le comportement peut être remplacé:
la source
Marshal.load(Marshal.dump(h))
.Comme d'autres l'ont souligné, le
clone
fera. Sachezclone
qu'un hachage fait une copie superficielle. C'est-à-dire:Ce qui se passe, c'est que les références du hachage sont copiées, mais pas les objets auxquels elles font référence.
Si vous voulez une copie complète, alors:
deep_copy
fonctionne pour tout objet pouvant être rassemblé. La plupart des types de données intégrés (Array, Hash, String, etc.) peuvent être rassemblés.Marshalling est le nom de Ruby pour la sérialisation . Avec le marshaling, l'objet - avec les objets auxquels il fait référence - est converti en une série d'octets; ces octets sont ensuite utilisés pour créer un autre objet comme l'original.
la source
Marshal.load(Marshal.dump(o))
la copie en profondeur? Je ne peux pas vraiment comprendre ce qui se passe dans les coulissesh1[:a] << 'bar'
modifiez l'objet d'origine (la chaîne pointée par h1 [: a]) mais si vous deviez le faire à lah1[:a] = "#{h1[:a]}bar"
place, vous créeriez un nouvel objet chaîne et le pointeriezh1[:a]
là, tandis queh2[:a]
est pointant toujours vers l'ancienne chaîne (non modifiée).Si vous utilisez Rails, vous pouvez faire:
http://apidock.com/rails/Hash/deep_dup
la source
Hash peut créer un nouveau hachage à partir d'un hachage existant:
la source
Je suis également un débutant à Ruby et j'ai rencontré des problèmes similaires lors de la duplication d'un hachage. Utilisez le suivant. Je n'ai aucune idée de la vitesse de cette méthode.
la source
Comme mentionné dans la section Considérations sur la sécurité de la documentation de Marshal ,
Voici un exemple sur la façon de cloner à l'aide de JSON dans Ruby:
la source
Utilisation
Object#clone
:(Confusément, la documentation de
clone
indique queinitialize_copy
c'est le moyen de contourner cela, mais le lien pour cette méthodeHash
vous indique à lareplace
place ...)la source
Étant donné que la méthode de clonage standard préserve l'état figé, elle ne convient pas pour créer de nouveaux objets immuables basés sur l'objet d'origine, si vous souhaitez que les nouveaux objets soient légèrement différents de l'original (si vous aimez la programmation sans état).
la source
Le clone est lent. Car les performances devraient probablement commencer par un hachage vierge et une fusion. Ne couvre pas le cas des hachages imbriqués ...
la source
C'est un cas particulier, mais si vous commencez avec un hachage prédéfini que vous souhaitez récupérer et faire une copie, vous pouvez créer une méthode qui renvoie un hachage:
Le scénario particulier que j'avais était que j'avais une collection de hachages de schéma JSON où certains hachages se sont construits sur d'autres. Je les définissais initialement comme des variables de classe et j'ai rencontré ce problème de copie.
la source
vous pouvez utiliser ci-dessous pour copier en profondeur les objets Hash.
la source
Puisque Ruby a un million de façons de le faire, voici une autre façon d'utiliser Enumerable:
la source
Une manière alternative à Deep_Copy qui a fonctionné pour moi.
Cela a produit une copie profonde puisque h2 est formé en utilisant une représentation matricielle de h1 plutôt que des références de h1.
la source