Как понимать символы в Ruby - PullRequest
       24

Как понимать символы в Ruby

81 голосов
/ 26 февраля 2010

Несмотря на чтение " Понимание символов Ruby ", я все еще смущен представлением данных в памяти, когда речь заходит об использовании символов. Если символ, два из которых содержатся в разных объектах, существует в одной и той же ячейке памяти, то как получается, что они содержат разные значения? Я ожидал, что одна и та же ячейка памяти будет содержать одно и то же значение.

Это цитата по ссылке:

В отличие от строк, символы с одинаковыми именами инициализируются и существуют в памяти только один раз во время сеанса ruby ​​

Я не понимаю, как удается дифференцировать значения, содержащиеся в одной и той же ячейке памяти.

Рассмотрим этот пример:

patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }

patient1.each_key {|key| puts key.object_id.to_s}
3918094
patient2.each_key {|key| puts key.object_id.to_s}
3918094

patient1 и patient2 оба хэши, это нормально. :ruby однако является символом. Если бы мы должны были вывести следующее:

patient1.each_key {|key| puts key.to_s}

Тогда что будет выводиться? "red" или "programming"?

Забывая хэши на секунду, я думаю, что символ - это указатель на значение. У меня есть следующие вопросы:

  • Можно ли присвоить значение символу?
  • Является ли символ просто указателем на переменную со значением в ней?
  • Если символы глобальные, значит ли это, что символ всегда указывает на одну вещь?

Ответы [ 11 ]

0 голосов
/ 11 мая 2014

Один из простых способов обдумать это - подумать: «А что, если бы я использовал строку, а не символ?

patient1 = { "ruby" => "red" }
patient2 = { "ruby" => "programming" }

Это совсем не смущает, верно? Вы используете "ruby" в качестве ключа в хэше .

"ruby" - строковый литерал, так что это значение. Адрес памяти или указатель вам недоступен. Каждый раз, когда вы вызываете "ruby", вы создаете его новый экземпляр, то есть создаете новую ячейку памяти, содержащую то же значение - "ruby".

Затем в хэше говорится: «Какое значение моего ключа? О, это "ruby"». Затем сопоставляет это значение с «красным» или «программированием». Другими словами, :ruby не обращается к "red" или "programming". Хэш отображает :ruby на "red" или "programming".

Сравните это с тем, если мы используем символы

patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }

Значение :ruby также "ruby", эффективно.

Почему? Потому что символы по сути строковые константы . Константы не имеют нескольких экземпляров. Это тот же адрес памяти. И адрес памяти имеет определенное значение, разыменованное. Для символов имя указателя является символом, а разыменованное значение является строкой, которая соответствует имени символа, в данном случае, "ruby".

В хеше вы используете не символ, указатель, а значение, на которое указывает ссылка. Вы используете не :ruby, а "ruby". Хеш затем ищет ключ "ruby", значение "red" или "programming", в зависимости от того, как вы определили хеш.

Концепция смены парадигмы и возврата в исходное состояние заключается в том, что значение символа является совершенно отдельным понятием от значения, сопоставленного с хешем, с учетом ключа этого хеша.

...