Sven Suska <sven715rt / suska.org> writes: > Sven Suska schrieb: > > If it were just a normal hash, we would have to lock the object manually: > Start locking from this point, before you do a check. > if users.has_key(new_nickname) > raise "Nickname already exists" > end > # hash could be modified here, if not locked!!! > # if another thread would have stored a user with the same nickname > # just now, then this data would be overwritten in the next > statement. If you start locking at this point, then in between the check and the insertion another check and insertion could have occurred and the following insertion effectively undoes that insertion. > users[new_nickname] = user_data > If "users" were in this "partially_frozen" state, then we could write: > > begin > users[new_nickname] = user_data > rescue CantChangeExistingDataError > raise "Nickname already exists" > end For Hash in official ruby implementation, since #= is implemented in C without any yielding, #= is effectively an atomic operation. But since you want to throw an exception if there is already existing entry, you'd still need a lock to do the check-and-insert atomically. In another thread, Ryan Davis brought up purely functional data structure. However, that won't lift the necessity of locking in your example case because the users list would have to be a global, shared resource and you are trying to do something akin to the P() operation of sempahore. Unless Hash already have an atomic check-before-set operation, you can't get around it the need of having a lock. [And no, Hash has no such thing yet. Set#add? is similar to what you're looking for but it's not atomic]. YS.