Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

i'm using Ruby 1.9.3

I figured out that you can use an array, or a hash as hash key in ruby:

h =

h[] = "Why?"
h[] # Output: "Why?"

h[] = "It doesn't make sense"
h[] # Output: "It doesn't make sense"

But an object works differently...

h[] = "LOL"
h[] # Output: "nil"

But this one works as expected:

o =

h[o] = "LMAO"
h[o] # Output: "LMAO"

Tried this:

o =           # Output: #<Object:0x2c78c10>
h["#<Object:0x2c78c10>"] # Output: nil

Tried it in Python and PHP and it throws an error.

I'm just curious about how it works, and why would you want to use an array, or a hash as hash key in ruby?


share|improve this question
up vote 4 down vote accepted

Why wouldn't you? You can use any object as a Hash key in Ruby. (Well, any object that responds to hash and eql?, but since there are definitions of those in Object, that's pretty much all objects.) It would be strange and inconsistent if you would arbitrarily exclude two classes from that.

share|improve this answer

Why limit the keys by a limited set of types? As long as it responds to hash, which is how hashes keep track of the key. Both Proc and lambda respond to hash and so can be used. As well as any other object, unless you explicitly remove that method from the object.

my_proc = { "Hello World #{}!"}
my_hash = { my_proc => 'a proc', => "a proc that was called at #{}" , [3, 2, 1] => 'My 3, 2, 1 array'}
my_hash.default = "There is no key with this value"
puts my_hash[my_proc]
puts my_hash[].inspect
puts my_hash[].inspect
puts my_hash[[3, 1, 2].sort.reverse]
puts my_hash
share|improve this answer

Well, you probably know this much already; but for starters, I'd say that's probably very bad practice. Still, it's an interesting functionality question, so I'll give it a shot...

From what I understand, Ruby maintains its empty arrays and hashes all as one singleton object, just as Nil is a single object in the entire program. If you declare 5 arrays with nothing in them, they're all the same reference - just like if you made 5 similar strings in C#, Javascript (and if I remember right, Ruby). They likely become seperate instances once values are added to them.

However, there are valid reasons to maintain's as seperate instances - the most common use I would know of is as multithreading tokens; times when you want to maintain something by hash map, but since it's so code-internal, a string isn't the most logical key.

The root of my answer, as I understand it, is that those classes work in kinda-exceptional ways within the language that you may not see with other types. I haven't used Ruby in a while, so I may need to get this verified by others.

share|improve this answer
So maybe arrays and hashes in Ruby are lazy loaded? – random_guy May 13 '13 at 21:23
The reason that when called as a key doesn't match is because it is a new Object. It did not exist until you called it when you were trying to retrieve the key. This makes perfect sense, as you show when you store that new Object and then query the Hash for that value. – vgoff May 13 '13 at 22:06
The reason why they behave differently, is because they override hash and sql?, not because of some magical singleton object pooling caching thingy. I don't know of any Ruby implementation that does something even remotely similar to what you describe, and if there were, that would be a private internal implementation optimization detail that would not be allowed to change user-visible behavior. – Jörg W Mittag May 13 '13 at 22:37

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.