# Hash keys

**URL:** <https://www.ruby-forum.com/t/hash-keys/128816>\
**Category:** Ruby\
**Created:** [February 11, 2008, 8:32pm UTC](https://www.ruby-forum.com/t/hash-keys/128816 "2008-02-11T20:32:32Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 8:32pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/1 "2008-02-11T20:32:32Z")

</div>

I ran into something I hadn’t realized (common occurrence). Keying a  
hash with a symbol is not the same as using a string. I guess it makes  
sense, but I’ve seen it done both ways, and I had been always using  
symbols for my keys. But then I ran into an issue on loading an external  
YAML object into a hash, and didn’t realize it was keyed with strings so  
I got errors the first time around.

So two questions:

1. What is the preferred method of keying hashes? Symbols, strings,  
other?
2. Is there a smooth way to handle hashes that may have been keyed in  
either fashion?

Thanks

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 9:52pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/2 "2008-02-11T21:52:16Z")

</div>

On 2/11/08, J. Cooper [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I ran into something I hadn’t realized (common occurrence). Keying a  
> hash with a symbol is not the same as using a string. I guess it makes  
> sense, but I’ve seen it done both ways, and I had been always using  
> symbols for my keys. But then I ran into an issue on loading an external  
> YAML object into a hash, and didn’t realize it was keyed with strings so  
> I got errors the first time around.
> 
> So two questions:
> 
> 1. What is the preferred method of keying hashes? Symbols, strings,  
> other?

Symbol keys  
+ :a is one less keystroke than “a”  
+? performance of Hash with symbol keys MIGHT be slightly  
faster, but probably insignificant.  
- More symbols get interned which can’t get garbage  
collected, even after the hash is.

String keys

```
    + keys can be GCed when removed from hash, or when the hash is 

```

GCed.

> 1. Is there a smooth way to handle hashes that may have been keyed in  
> either fashion?

Rails is probably most responsible for popularizing symbol keys.  
ActiveSupport implements a HashWithIndifferentAccess which can use  
either symbols or strings interchangeably in access methods.  
Internally it uses string keys.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 9:58pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/3 "2008-02-11T21:58:44Z")

</div>

On Feb 11, 2008 8:32 PM, J. Cooper [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I ran into something I hadn’t realized (common occurrence). Keying a  
> hash with a symbol is not the same as using a string. I guess it makes  
> sense, but I’ve seen it done both ways, and I had been always using  
> symbols for my keys. But then I ran into an issue on loading an external  
> YAML object into a hash, and didn’t realize it was keyed with strings so  
> I got errors the first time around.
> 
> So two questions:
> 
> 1. What is the preferred method of keying hashes? Symbols, strings,  
> other?  
> ----------------- 8\< -----------------  
> Symbols, look at this code

Symbol.send( :define\_method, :to\_proc ){  
lambda{|x| x.send self }  
} unless RUBY\_VERSION === /^1.9/

string\_keys = %w{a b c}  
symbol\_keys = string\_keys.map(&:to\_sym)

string\_hash = Hash[\*string\_keys.zip([42]\*3).to\_a.flatten ]  
symbol\_hash = Hash[\*symbol\_keys.zip([42]\*3).to\_a.flatten ]

p [:symbol, symbol\_hash]  
p [:string, string\_hash]  
puts “So far everything looks fine”  
string\_hash.each\_pair do |k,v| k \<\< “…” end  
------------------------ 8\< ----------------------  
Ruby does a fine job by freezing keys of hashes, but I prefer to use  
immutable objects as keys whenever it is possible  
for that very reason, in our case that favors Symbols

> 1. Is there a smooth way to handle hashes that may have been keyed in  
> either fashion?  
> Handle them? If I pretended to be even more stupid than I actually  
> believe to be I would say yes sure  
> a\_hash.clear 😉

But I guess that you want to change from one to the other, let me show  
you from String to Symbol  
------------------------ 8\< ----------------------

### Do not do this at home 🙂

Array.send :define\_method, :each\_with\_index do  
count = 0  
inject([]){|iwi,e| count+=1; iwi \<\< [e,count=count+1]}  
end unless RUBY\_VERSION === /^1.9/  
string\_hash = %w{A Brave New  
World}.each\_with\_index.inject({}){|h,(v,i)| h.update v =\> i }  
p string\_hash

symbol\_hash = Hash[\*string\_hash.to\_a.map{|k,v|[k.to\_sym,v]}.flatten ]  
p symbol\_hash  
------------------------ 8\< ----------------------  
HTH  
Robert

> ## Thanks
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

–  
[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

Whereof one cannot speak, thereof one must be silent.  
Ludwig Wittgenstein

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 10:30pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/4 "2008-02-11T22:30:34Z")

</div>

On 11.02.2008 20:32, J. Cooper wrote:

> I ran into something I hadn’t realized (common occurrence). Keying a  
> hash with a symbol is not the same as using a string. I guess it makes  
> sense, but I’ve seen it done both ways, and I had been always using  
> symbols for my keys. But then I ran into an issue on loading an external  
> YAML object into a hash, and didn’t realize it was keyed with strings so  
> I got errors the first time around.
> 
> So two questions:
> 
> 1. What is the preferred method of keying hashes? Symbols, strings,  
> other?

It depends: my personal convention is this: use symbols if the set of  
keys is limited and probably known beforehand; use strings if the data  
is read from an external resource (e.g. a file) and there could be  
arbitrary key values.

> 1. Is there a smooth way to handle hashes that may have been keyed in  
> either fashion?

I do not think there is a smooth one size fits all way. You could of  
course convert a Hash containing on set of keys to the other one. I  
don’t think it is worthwhile though and haven’t seen it so far.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 10:58pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/5 "2008-02-11T22:58:24Z")

</div>

Alright, so in general if the hash is going to interact with the outside  
world, I should use string keys, and it’s not worth it particularly to  
worry about handling mismatch (unless I’m embarking on a Rails-sized  
framework)?

I guess I had figured symbols made more sense, as a key is kinda just an  
identifier and there isn’t a reason to perform string functions on it.  
But I didn’t realize the deal with the GC

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 10:02pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/6 "2008-02-11T22:02:51Z")

</div>

On Feb 11, 2008 9:51 PM, Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > other?
> 
> Symbol keys  
> + :a is one less keystroke than “a”  
> +? performance of Hash with symbol keys MIGHT be slightly  
> faster, but probably insignificant.  
> - More symbols get interned which can’t get garbage  
> collected, even after the hash is.  
> Hmm very interesting but is this not rather an implementation choice?  
> Which does not make the information less valuable of course, just  
> curious?

Cheers  
Robert

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 11:13pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/7 "2008-02-11T23:13:50Z")

</div>

Rick DeNatale wrote:

> > 1. What is the preferred method of keying hashes? Symbols, strings,  
> > String keys
> 
> ```
> + keys can be GCed when removed from hash, or when the hash is GCed.
> 
> ```

Another thing to look at is symbols are unique, whereas each time you  
use a string literal to access the hash, you are creating a new object:

h1 = { :a =\> 1, :b =\> 2 }  
h2 = { “a” =\> 1, “b” =\> 2 }

h2[“a”] # Creates a one-time use string “a”  
h1[:a] #No new object created, :a already exists

But if you are creating lots and lots of symbols, then that’s lots of  
unique objects being created which are not going to be garbage  
collected.

Of course, strings and symbols are not the only choices for hash keys,  
any object can be used. What you want may depend on the circumstances.

-Justin

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 12, 2008, 10:45pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/8 "2008-02-12T22:45:35Z")

</div>

On 11.02.2008 22:58, J. Cooper wrote:

> Alright, so in general if the hash is going to interact with the outside  
> world, I should use string keys, and it’s not worth it particularly to  
> worry about handling mismatch (unless I’m embarking on a Rails-sized  
> framework)?

I am not sure what you mean by “handling mismatch”. If by mismatch you  
mean access with symbols and strings: I usually do not worry about this,  
because I write the code that puts data into the Hash and reads it - so  
I know what happens or can control. Personally I prefer uniform access.

If by “outside world” you mean, a “data source that you do not control”  
(e.g. web server logfiles, CSV data) then yes, in those cases I would  
use Strings, namely the strings I read from that source.

> I guess I had figured symbols made more sense, as a key is kinda just an  
> identifier and there isn’t a reason to perform string functions on it.  
> But I didn’t realize the deal with the GC

Well, if there is a limited set (e.g. states of an object like :open and  
:closed for an IO stream) then it makes perfectly sense to use symbols.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![nefigah](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e47774/32.png) [@nefigah](https://www.ruby-forum.com/u/nefigah)\
**Post date:** [February 11, 2008, 11:40pm UTC](https://www.ruby-forum.com/t/hash-keys/128816/9 "2008-02-11T23:40:54Z")

</div>

On Feb 11, 2:27 pm, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I do not think there is a smooth one size fits all way. You could of  
> course convert a Hash containing on set of keys to the other one. I  
> don’t think it is worthwhile though and haven’t seen it so far.

[http://api.rubyonrails.org/classes/HashWithIndifferentAccess.html](http://api.rubyonrails.org/classes/HashWithIndifferentAccess.html)

[http://facets.rubyforge.org/rdoc/core/classes/Hash.html#M000070](http://facets.rubyforge.org/rdoc/core/classes/Hash.html#M000070)

(Neither are a refutation of your statements, just throwing a few data  
points into a discussion that I’m too busy to formally join at the  
moment.)
