2009-11-05 4 views
4

Supposons que vous ayez ceci:modification concurrente en traversant un rubis Hash

def wipeProduct(hash, nameToDelete) 
    hash.each do |i| 
    key = i[0] 
    productName = i[1].first 
    hash.delete(key) if productName==nameToDelete 
    end 
end 

Je ne suis pas sûr qu'il est sûr de supprimer les choses d'un hachage pendant que vous êtes itérer sur les paires clé-valeur de hachage. J'ai vérifié la documentation du RI mais je n'ai rien vu à propos de la modification simultanée sur Hash.

Je sais que vous pouvez réécrire cette

def wipeProduct(hash, nameToDelete) 
    keysToDelete = [] 
    hash.each do |i| 
    key = i[0] 
    productName = i[1].first 
    keysToDelete << key if productName==nameToDelete 
    end 
    keysToDelete.each {|key| hash.delete(key) } 
end 

ou même:

def wipeProduct(hash, nameToDelete) 
    hash.reject!{|key,value| nameToDelete==value.first} 
end 

mais je veux savoir si une modification concurrente comme indiqué dans le premier exemple ci-dessus est un problème? (Il ne semble pas être quand je cours le code)

Question: Est-ce que quelqu'un sait quelle est la position sur la modification simultanée avec Hash? (... et les autres collections?) - et j'aimerais bien avoir des liens vers des ressources documentant cela si vous voulez.

Répondre

1

Tant qu'aucun autre thread n'essaye d'accéder au hachage, aucune de ces méthodes ne convient. S'il existe d'autres threads pouvant accéder à ce hachage, aucune de ces approches n'est explicitement sécurisée pour les threads. Vous devez les sécuriser, assurez-vous que votre méthode acquiert un verrou pendant la modification du hachage, et que tout se passera bien.

Personnellement j'irais avec le reject_if destructeur! C'est un code plus propre et accomplit la même chose sans reproduire le code existant.