Issue #14336 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


Matz, I'd just like to remind you that this discussion is not about unfamiliarity.

When I suggested the removal of symbols from the language several years ago I already understood the differences between Symbols and Strings by then. I'd arguee that most Rubyists do, and yet, many would love to see Symbols gone from the language (and certainly many of them want to keep them apparently).

Most of the confusion caused by the existence of symbols come from hash[:a] != hash['a'] and this leads to bugs every single day in some Ruby project out there. It's pretty rare that someone would intentionally want hash[:a] to be different from hash['a']. For most code bases that would usually mean a bug.

The fact that the new hash syntax creates symbols as keys just makes it worse, as people usually prefer the new syntax as they have to type much less. So, here's what typically happens in a Ruby application:

~~~ ruby
unless user = user_from_cache(session_id)
  user = { id: 1, username: 'rodrigo', permissions: { may_view_reports: true } }
  store_user_in_cache session_id, user
end
~~~

Now, suppose user_from_cache deserialize from Redis, while store_user_in_cache serialize to Redis. The Redis driver supports symbols as keys and will convert them to string. When deserializing back, the hash keys will be strings. That means calling `user[:id]` would be nil if user was retrieved from cache. This sort of things happens very often unfortuntately so we can't just pretend that all sorts of problems that come from the existence of symbols are simply caused by people being ignorant among the conceptual difference between symbols and strings. They cause real pain to many rubyists, even experienced ones.

We never know whether hash keys should be considered symbols or strings when we get them from somewhere else. For example, Sequel models have a #to_h instance method and the only way we can know whether keys are symbols or strings is by either looking at the documentation or trying it and see what to expect. This is more work than we'd like to have when dealing with hashes all over the places. This is more time that we need to take to read somewhere else because for some people it's important that hash[:a] would be different from hash['a'].

This has nothing to do with unfamiliarity. There's a gray area anyway when we talk about what should be considered an identifier. Having to think about whether symbols or strings should be used for a particular case is also a waste of time for many cases while designing Ruby code, in my opinion.

You often say that symbols already exist in other languages and has been borrowed from them. Since I don't know those languages, let me ask you: do those languages support the equivalent of Ruby's Hash and allow both strings and symbols as keys? If so, haven't their users ever complained about that?

It feels very confusing to me, even if you clearly understand the conceptual differences among symbols and strings.

That's why I suggested Hash to be implemented as HashWithIndifferentAccess in issue #7797.

If we can't get rid of Symbols, but if issue #7797 would be accepted, I guess most of the confusion in existing Ruby code bases would be gone. Could you please reconsider it?

----------------------------------------
Feature #14336: Create new method String#symbol? and deprecate Symbol class
https://bugs.ruby-lang.org/issues/14336#change-69482

* Author: dsferreira (Daniel Ferreira)
* Status: Rejected
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
From  the discussions on the three previous issues related to the String vs Symbol subject ([5964](https://bugs.ruby-lang.org/issues/5964), [7792](https://bugs.ruby-lang.org/issues/7792), [14277](https://bugs.ruby-lang.org/issues/14277)) there are some conclusions we can assume:
* Current String vs Symbol is not the ideal scenario. See: Matz and Koichi comments.
* Current philosophy is to use Symbols as identifiers and Strings when strings are needed.
* Current situation is that Symbols are being used in many code bases as strings except for strings that really need the String methods.
* Current situation is that we are designing APIs to handle both String and Symbol inputs forcing an overhead of API development.

I propose the deprecation of `Symbol` class and the introduction of `String#symbol?`.

```ruby
foo = :foo
foo.class # => String
foo.symbol? # => true
bar = "bar"
bar.class # => String
bar.symbol? # => false
```

For backwards compatibility transition path I propose:

```ruby
class Symbol
  def self.===(var)
    warn ("Warning message regarding deprecated class")
    if var.class == Symbol
      true
    elsif var.class == String && var.symbol?
      true
    else
      false
    end
  end
end

class String
  def is_a?(klass)
    case klass
    when String
      true
    when Symbol
      self.symbol?
    else
      false
    end
  end
end
```



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>