Использование символов Ruby

Впервые я попробовал изучать Ruby 2 года назад, сейчас я начал снова. Причина, по которой я остановился, заключалась в том, что я не мог понять класс Symbol. И теперь я снова в том же положении, совершенно заблудившись в том, когда и почему вы используете символы. Я прочитал другие посты на Stackoverflow, а также Googled для нескольких объяснений. Но я этого пока не понимаю.

Сначала я подумал, что символы - это просто способ создать своего рода «константу с именем». без необходимости проходить тот же процесс, что и, скажем, в Java.

:all 

вместо создания константы с произвольным значениемpublic static final String ALL = 8;

Однако это не имеет особого смысла, когда вы используете его, например,attr_accessor :first_name etc. Символы - это просто легкий класс String? У меня проблемы с пониманием того, как я должен интерпретировать, когда и как использовать символы как в моих собственных классах, так и в рамках.

 Andrew Grimm16 июл. 2012 г., 01:44
Если вам от этого станет легче, создатели Ruby сами не понимают, когда использовать строки, а когда использовать символы.Class.new.methods вернул массив строк в 1.8 и массив символов в 1.9. :)
 David Hoelzer30 авг. 2016 г., 13:33
Возможный дубликатUnderstanding Symbols In Ruby

Ответы на вопрос(4)

Решение Вопроса

Короче, символыare легкие строки, но они также являются неизменяемыми и не подлежат сборке мусора.

Вам следуетnot используйте их в качестве неизменяемых строк в задачах обработки данных (помните, что после создания символа он не может быть уничтожен). Вы обычно используете символы для именования вещей.

# typical use cases

# access hash value
user = User.find(params[:id])

# name something
attr_accessor :first_name

# set hash value in opts parameter
db.collection.update(query, update, multi: true, upsert: true)  

Давайте возьмем первый пример,params[:id], В умеренно больших приложениях rails могут быть сотни / тысячи тех, кто разбросан по базе кода. Если мы получили доступ к этому значению через строку,params["id"], это означает, что каждый раз выделяется новая строка (и эта строка должна быть собрана впоследствии). В случае символа это на самом делеthe same символ везде Меньше работы для распределителя памяти, сборщика мусора и даже вас (: быстрее набрать, чем"")

Если у вас есть простая строка из одного слова, которая часто встречается в вашем коде, и вы не делаете с ней что-то непонятное (интерполяция, gsub, upcase и т. Д.), То, скорее всего, это хороший кандидат на то, чтобы стать символом.

However, does this apply only to text that is used as part of the actual program logic such as naming, not text that you get while actually running the program...such as text from the user/web etc?

Я не могу вспомнить ни одного случая, когда я хотел бы превратить данные из пользователя / сети в символ (возможно, за исключением разбора параметров командной строки). Главным образом из-за последствий (когда-то созданные символы живут вечно).

Также многие редакторы предоставляют разные цвета для символов, чтобы выделить их в коде. Посмотрите на этот пример

symbol vs string

 12 июл. 2012 г., 10:20
@ Чувак: да, вы могли бы сказать это. Обратите внимание, что символ не может быть заменен вместо строки. Это похоже на строку, но с точки зрения рубина, это не так. Вы всегда можете разыграть,:foo.to_s.
 11 авг. 2016 г., 10:54
@yozzz: спасибо! Убрал неработающую ссылку, так как остального ответа должно хватить.
 LuckyLuke12 июл. 2012 г., 10:12
Таким образом, причина наличия Symbol в том, что String является изменяемым, и, следовательно, программист сам может повысить производительность программы, используя неизменный класс Symbol?
 LuckyLuke12 июл. 2012 г., 10:17
Таким образом, символ представляет собой строку со свойствами, равнымиstatic и неизменным на других языках?
 12 июл. 2012 г., 10:15
Вам следуетnot используйте их в качестве неизменяемых строк в задачах обработки данных (помните, что после создания символа он не может быть уничтожен). Вы обычно используете символы для именования вещей.

O 'ReillyRuby Cookbook (стр. 15) цитирует слова Джима Вейриха:

If the contents (the sequence of characters) of the object are important, use a string. If the identity of the object is important, use a symbol.

Символы, как правило, используются в качестве хэш-ключей, потому что этоidentity ключа, который важен. Символы также требуются при передаче сообщений с использованием определенных методов, таких какObject#send.

 09 дек. 2015 г., 13:21
Object#send делаетnot требуется символ.
 09 дек. 2015 г., 16:19
@SergioTulentsev Хотя текущие версии МРТ принимают строковые аргументы для этого метода,earlier versions did not, Тем не менее, если реализация не изменилась снова, #send преобразует строковые аргументы в символы, потому что именно так Ruby внутренне идентифицирует имена методов. Ваш пробег (и конкретные реализации) могут отличаться.

Реализация Ruby обычно имеет таблицу, в которой хранятся имена всех классов, методов и переменных. Это относится к названию метода по позиции в таблице, избегая дорогостоящих сравнений строк. Но вы также можете использовать эту таблицу и добавить к ней значения:symbols.

Если вы пишете код, который использует строки в качестве идентификаторов, а не для их текстового содержимого, рассмотрите символы. Если вы напишите метод, который ожидает, что аргумент будет либо «мужской» или "женский", рассмотрите возможность использования:male а также:female , Сравнение двух символов на равенство выполняется быстрее, чем строки (поэтому символы делают хорошие хеш-ключи).

Символы используются для обозначения вещей на языке: названия классов, имена методов и т. Д. Это очень похоже на строки, за исключением того, что они никогда не могут быть собраны мусором, и тестирование на равенство оптимизировано, чтобы быть очень быстрым.

Реализация Java очень похожа, за исключением того, что она недоступна для использования во время выполнения. Я имею в виду, когда вы пишете код Java, какobj.someMethod(4)строка "someMethod" преобразуется компилятором в символ, который внедряется в таблицу поиска в файле .class. Эти символы похожи на «специальные»; строки, которые не являются сборщиком мусора и которые очень быстро сравнивать на равенство. Это почти идентично Ruby, за исключением того, что Ruby позволяет создавать новые символы во время выполнения, тогда как Java позволяет это только во время компиляции.

Это похоже на создание новых методов - Java позволяет это во время компиляции; Ruby позволяет это во время выполнения.

Ваш ответ на вопрос