Issue #7792 has been updated by jeremyevans0 (Jeremy Evans).


phluid61 (Matthew Kerwin) wrote:
>  > Take the Sequel library for instance.
>  
>  No thanks, apparently the authors don't know the difference between Symbols
>  and Strings.

Sequel uses symbol keys instead of string keys intentionally.  Sequel maps SQL features directly to ruby objects, mapping SQL identifiers (columns/tables/aliases) to ruby symbols and SQL strings to ruby strings. SQL query results can be thought of as a mapping of SQL identifiers to the values for each identifier in the query, thus Sequel uses a hash with symbol keys.

Ruby uses symbols in a very similar way to how SQL uses identifiers, with symbols basically acting as an identifier.  The fact that ruby uses symbols as identifiers should be obvious to anyone who has looked at MRI's implementation, where a symbol is simply an alternate representation of an ID (the internal identifier type that MRI uses to map names to values):

#define ID2SYM(x) (((VALUE)(x)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG)
#define SYM2ID(x) RSHIFT((unsigned long)(x),RUBY_SPECIAL_SHIFT)

The basic philosophical difference between a symbol and a string is a ruby symbol is an identifier, while a ruby string just represents arbitrary data.  You should convert a string to a symbol if you know that the data the string contains represents an identifier you would like to use.  You should convert a symbol to a string if you are using name of the identifier as data.
----------------------------------------
Feature #7792: Make symbols and strings the same thing
https://bugs.ruby-lang.org/issues/7792#change-36000

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/