From: "drbrain (Eric Hodel)" Date: 2013-02-07T05:19:51+09:00 Subject: [ruby-core:51946] [ruby-trunk - Feature #7792][Rejected] Make symbols and strings the same thing Issue #7792 has been updated by drbrain (Eric Hodel). Status changed from Open to Rejected =begin This proposal has no description of how to overlay the functionality of strings (mutable) with symbols (immutable). This was previously tried during 1.9 which had such a plan but was ultimately rejected. Due to a previous attempt and failure along with the lack of a concrete plan in this feature request I will reject this. As to symbols or strings as hash keys, you should almost always use strings. This is the current community best-practice consensus. You should only use symbols as keys in a Hash if you have a small, fixed set of keys and do not use user input to look up items in the hash. Converting a string to a symbol you look up in a hash is not recommended. You have created two hash lookups out of one (the first for string to symbol mapping, the second for the lookup in your hash) and you risk a DoS as symbols are not garbage collected. Consider this benchmark: require 'benchmark' N = 10_000_000 Benchmark.bmbm do |bm| bm.report 'NULL' do h = { 'foo' => 'bar'} N.times do # null end end bm.report 'string key, string lookup' do h = { 'foo' => 'bar' } N.times do h['foo'] end end bm.report 'symbol key, symbol lookup' do h = { :foo => 'bar' } N.times do h[:foo] end end bm.report 'symbol key, string intern lookup' do h = { :foo => 'bar' } N.times do h['foo'.intern] end end end Here are the results: Rehearsal -------------------------------------------------------------------- NULL 0.440000 0.000000 0.440000 ( 0.448186) string key, string lookup 1.870000 0.000000 1.870000 ( 1.866935) symbol key, symbol lookup 0.660000 0.000000 0.660000 ( 0.661466) symbol key, string intern lookup 2.230000 0.000000 2.230000 ( 2.222772) ----------------------------------------------------------- total: 5.200000sec user system total real NULL 0.430000 0.000000 0.430000 ( 0.434306) string key, string lookup 1.860000 0.000000 1.860000 ( 1.862942) symbol key, symbol lookup 0.680000 0.000000 0.680000 ( 0.681767) symbol key, string intern lookup 2.270000 0.010000 2.280000 ( 2.264888) While symbol key and symbol lookup is 2.7 times faster than string key and string lookup, it is also 1.2 times faster than interning a string for a symbol lookup. =end ---------------------------------------- Feature #7792: Make symbols and strings the same thing https://bugs.ruby-lang.org/issues/7792#change-35945 Author: rosenfeld (Rodrigo Rosenfeld Rosas) Status: Rejected Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: Next Major Recently I had to replace several of my symbols to plain strings in my project. Here is what happened: I generated some results with some class that would add items to an array like this: results << {id: 1, name: 'abc'} Then I would store such results in cache using Redis, encoded as a JSON string. But then when I restore the data from cache the hash will be {'id' => 1, 'name' => 'abc'}. This wasn't a problem until recently because I never used the results directly in the same request before and would always use the value stored on Redis and parsed by JSON. But recently I had to use the values directly in a view. But then I had a problem because I would have to use symbols in the results for the first time and strings the next times when the result was available on cache. I really don't want to care about memory management in Ruby if possible and symbols forces me to abandon the new sexy hash syntax many times. Now I have to write results << {'id' => 1, 'name' => 'abc} when I'd prefer to write results << {id: 1, name: 'abc} This is not the first time I had a bad user experience due to symbols being different from strings. And I'm not the only one or ActiveSupport Hash#with_indifferent_access wouldn't be so popular and Rails wouldn't use it all the time internally. It is really bad when you have to constantly check how you store your keys in your hashes. Am I using symbols or strings as keys? If you use the wrong type on plain hashes you can find a bad time debugging your code. Or you could just use Hash#with_indifferent_access everywhere, thus reducing performance (I guess) and it is pretty inconvenient anyway. Or if you're comparing the keys of your hash in some "each" closure you have to worry about it being a symbol or a string too. Ruby is told to be programmers' friendly and it usually is. But symbols are certainly a big exception. -- http://bugs.ruby-lang.org/