Вход/Регистрация
Программирование на языке Ruby
вернуться

Фултон Хэл

Шрифт:

Но почему не воспользоваться просто строкой? Вообще-то можно. Многие, даже большинство системных методов, ожидающих символ в качестве параметра, соглашаются и на строку.

attr_reader :alpha

attr_reader "beta" # Так тоже можно.

На самом деле символ «похож» на строку в том смысле, что ему соответствует последовательность символов. Поэтому некоторые говорят, что «символ — это просто неизменяемая строка». Но класс

Symbol
не наследует классу
String
, а типичные операции над строками необязательно применимы к символам.

Также неправильно думать, что символы напрямую соответствуют идентификаторам. Из-за этого непонимания некоторые говорят о «таблице символов» (как если бы речь шла об ассемблированном объектном коде). В действительности это представление бессмысленно; хотя символы и хранятся в какой-то внутренней таблице (а как же иначе?), Ruby не дает к ней доступа, поэтому программистам все равно, существует она или нет.

Более того, символы даже не всегда выглядят как идентификаторы. Обычно это так, что бы под этим ни понимать, но символ может содержать и знаки препинания, если заключен в кавычки. Все показанные ниже символы допустимы:

sym1 = :"This is a symbol"

sym2 = :"This is, too!"

sym3 = :")(*&^%$" # И даже такой.

Можно даже использовать символы для определения переменных и методов экземпляра, но тогда для ссылки на них пришлось бы применять такие методы, как

send
и
instance_variable_get
. Вообще говоря, такая практика не рекомендуется.

6.1.1. Символы как перечисления

В языке Pascal и в поздних версиях С есть понятие перечисляемого типа. В Ruby ничего подобного быть не может, ведь никакого контроля типов не производится. Но символы часто используются как мнемонические имена; стороны света можно было бы представить как

:north
,
:south
,
:east
и
:west
.

Быть может, немного понятнее хранить их в виде констант:

North, South, East, West = :north, :south, :east, :west

Если бы это были строки, а не символы, то определение их в виде констант могло бы сэкономить память, но каждый символ все равно существует в объектном пространстве в единственном экземпляре. (Символы, подобно объектам

Fixnum
, хранятся как непосредственные значения.)

6.1.2. Символы как метазначения

Мы нередко пользуемся исключениями, чтобы уйти от кодов возврата. Но никто не мешает возвращать коды ошибки, если вам так хочется. К тому же в Ruby метод может возвращать более одного значения.

В таком механизме часто возникает необходимость. Когда-то символ NUL кода ASCII вообще не считался символом. В языке С есть понятие нулевого указателя (

NULL
), в Pascal есть указатель
nil
, в SQL NULL означает отсутствие какого бы то ни было значения. В Ruby, конечно, тоже есть свой
nil
.

Проблема в том, что такие метазначения часто путают с действительными значениями. В наши дни все считают NUL настоящим символом кода ASCII. И в Ruby нельзя сказать, что

nil
не является объектом; его можно хранить, над ним можно выполнять какие-то операции. Поэтому не вполне понятно, как интерпретировать ситуацию, когда
hash [key]
возвращает
nil
: то ли указанный ключ вообще не найден, то ли с ним ассоциировано значение
nil
.

Идея в том, что иногда символы могут выступать в роли подходящих метазначений. Представьте метод, который получает строку из сети (возможно, по протоколу HTTP или иным способом). При желании можно было бы вернуть нестроковое значение как индикатор исключительной ситуации.

str = get_string

case str

 when String

# Нормальная обработка.

 when :eof

# Конец файла, закрытие сокета и т.п.

 when :error

# Ошибка сети или ввода/вывода.

 when :timeout

# Ответ не получен вовремя.

end

Можно ли сказать, что это «лучше», чем механизм исключений? Необязательно. Но такую методику стоит иметь в виду, особенно когда приходится обрабатывать «граничные случаи», которые не считаются ошибками.

6.1.3. Символы, переменные и методы

Наверное, чаще всего символы применяются для определения атрибутов класса:

class MyClass

 attr_reader :alpha, :beta

 attr_writer :gamma, :delta

 attr_accessor :epsilon

 # ...

end

Имейте в виду, что в этом фрагменте на самом деле исполняется некий код. Например,

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

  • Читать дальше
  • 1
  • ...
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: