Я понимаю теоретическое различие между строками и символами. Я понимаю, что Символы предназначены для представления концепции или имени или идентификатора или метки или ключа, а строки - это мешок символов. Я понимаю, что Струны являются изменяемыми и преходящими, где Символы неизменны и постоянны. Мне даже нравится, как символы отличаются от строк в текстовом редакторе.
Меня беспокоит то, что на самом деле Символы настолько похожи на строки, что тот факт, что они не реализованы как строки, вызывает много головных болей. Они даже не поддерживают утиную печать или неявное принуждение, в отличие от другой известной "той же, но другой" пары Float и Fixnum.
Самая большая проблема, конечно, в том, что хеши, входящие в Ruby из других мест, такие как JSON и HTTP CGI, используют строковые ключи, а не символьные ключи, поэтому программы Ruby должны наклоняться назад, чтобы либо преобразовать их спереди, либо в время поиска. Простое существование HashWithIndifferentAccess
и его необузданное использование в Rails и других средах демонстрируют, что здесь проблема, зуд, который нужно поцарапать.
Может ли кто-нибудь сказать мне практическую причину, почему символы не должны быть заморожены? Кроме "потому что это всегда было сделано" (историческое) или "потому что символы не являются строками" (попрошайничество).
Рассмотрим следующее удивительное поведение:
:apple == "apple" #=> false, should be true
:apple.hash == "apple".hash #=> false, should be true
{apples: 10}["apples"] #=> nil, should be 10
{"apples" => 10}[:apples] #=> nil, should be 10
:apple.object_id == "apple".object_id #=> false, but that actually fine
Все, что потребуется, чтобы сделать следующее поколение рубистов менее запутанным:
class Symbol < String
def initialize *args
super
self.freeze
end
(и много другого взлома на уровне библиотеки, но все же, не слишком сложно)
См. также:
- http://onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.red
- http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol
- Почему мой код разбивается при использовании символа хэша вместо хеш-строки?
- Зачем использовать символы в качестве хеш-ключей в Ruby?
- Какие символы и как мы их используем?
- Ruby Symbols vs Strings in hashes
- Невозможно получить символ символов в Ruby
- http://blog.arkency.com/could-we-drop-symbols-from-ruby/
- Имеются ли символы Ruby, потому что строки изменяемы и не интернированы?
Обновление: я думаю, что Matz очень хорошо описывает случай class Symbol < String
: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9192 (спасибо Azolo за то, что он выкопал это, а также возможную ретракцию Маца.