Advanced Debugging Exercises

hash_array

So why is it that the original code (in comments) does not work?

When you use Hash.new([]) the default array for every key is the same array. It doesn’t create separate empty arrays for each key. It gives them all the same instance. So when you add an item to that array, it adds it to every key’s array because they all actually have the same array. += creates a new array instead of adding a new item to the existing array so it works fine.

1 Like

Thanks Jeremiah.

I now understand that with Hash.new([]) the default object [] is shared by the various keys; no separate empty array per key.

However, I still can’t figure out why the return value should be an empty hash.

  • Within the each_with_index iterarator , the index for each key gets to be shoveled into the default [], so
  • After the last iteration, shouldn’t the “positions” hash carry all unique keys pointing to the default array? (which contains the index of every element of the “self” array). Hope the question makes sense

Upon further thought, maybe this explanation holds. Will be great if peers/staff can help correct/cement the understanding of this subtlety.

  • The statement positions[item] << index never assigns/binds the default value (the default array object) to the key. Not for any key in self.

  • This is based on reading of This Post by Gary W.

Hash.new(x) returns x when a key isn’t found. It will be the
same x for every key and won’t store x in the hash, just return
it on a key miss.

  • In our case x is the default array.
  • By using positions[item] << index , the lack of binding operation ‘=’, means the default array x will never be returned and in turn assigned to positions[item]

Edit: I wrote this without seeing your second post. Your understanding is correct.

When you call positions[item] and the positions hash doesn’t have the key item, it returns the default array. It does not add the key item to the hash. It just returns the default array. So when you do
positions[item] << index
the code evaluates positions[item] first. When it finds that the positions hash doesn’t contain the key item, it just returns the default array without actually adding the key item to the array. Next it evaluates
<< index which just shoves index into the default array. Again, nothing in this code has actually added the key item to the positions hash, and nothing as assigned it a new value.

x += y is just shorthand for x = x + y. So let’s look at the working version of the code in that format:
positions[item] = positions[item] + [index]
See the assignment in there? That’s the important difference. When you assign a value to a hash’s key, the hash creates that key and stores the new value. That’s what the other code is lacking. No new value is ever actually assigned to the hash’s key. So first the code evaluates the right side of the equal sign:
positions[item] + [index]
So positions[item] returns the default array, but the it adds that array together with [index] to create a new array. Then the code evaluates the assignment. It assigns the new array to positions[item].

1 Like