From: mrilu Date: 2000-03-30T01:39:38+02:00 Subject: [ruby-talk:02254] Hashing Hey, Is there some reason ostruct.rb starts like this: class OpenStruct def initialize(hash=nil) @table = {} if hash for k,v in hash @table[k] = v end end end I think we're trying to make copy of hash 'hash' to @table. Why don't we say: @table = hash.dup or @table = hash.clone or @table = Hash.new.replace hash I guess it has something to do with semantics of the copying. It matters whether hash["a"] = "b" OpenStruct.new(hash)'s @table["key"] points to the same "b" or to other string with contents of "b" (in next example, whether openstruct.@table has something like c or like d). a = "a" b = "b"; p a.id # => 123 p b.id # => 456 c = a d = a.dup p c.id # => 123 p d.id # => 789 Or is it about key too, so that does it point to same "key" or to "key".dup ? Well, I think copying like in OpenStruct is so common that Hash should have builtin method for it. Now some other points of Hash. First about documentation. This excerpt is from my html-version of 1.4 documents. dup Returns a newly created hash table which has the save keys and values to the receiver. clone returns the complete copy of the original hash table, including freeze status and instance variables. On the other hand, dup copies the hash table containts. Note: I didn't see any other docs for Hash.clone. I try to fix few things here, but English is not my mother tongue so this just can't be right: dup Returns a newly created hash table which has same keys and values as the original hash instance. dup differs from clone by copying only hash contents (that is key,value-pairs). Example: foo = {"key"=>"value", "baz"=>"zak"} bar = foo.dup print bar[baz] # => "zak" clone Returns a newly created hash table which is a complete copy of the original hash instance. clone differs from dup by copying original hash table completely including key,value-pairs, freeze status and instance variables. Example: ... I'd like to see good examples for different copying strategies too (shallow, deep). One more point (raised in checking experimentation :): key = "key" value = "value" a = { key => value } b = a.invert c = b.invert print key.id # 537639674 print value.id # 537639554 print a[key].id # 537639554, it's value print b[value].id # 537639704, it's not key print c[key].id # 537639584, well, it's not value anymore It seems that invert makes clone (or duplicate) of it's keys and values. If this is important at all it should make it's way into documentation! Enough questions for one mail, isn't it?