Программирование на языке Ruby
Шрифт:
Также неправильно думать, что символы напрямую соответствуют идентификаторам. Из-за этого непонимания некоторые говорят о «таблице символов» (как если бы речь шла об ассемблированном объектном коде). В действительности это представление бессмысленно; хотя символы и хранятся в какой-то внутренней таблице (а как же иначе?), Ruby не дает к ней доступа, поэтому программистам все равно, существует она или нет.
Более того, символы даже не всегда выглядят как идентификаторы. Обычно это так, что бы под этим ни понимать, но символ может содержать и знаки препинания, если заключен в кавычки. Все показанные ниже символы допустимы:
Можно даже использовать символы для определения переменных и методов экземпляра, но тогда для ссылки на них пришлось бы применять такие методы, как
6.1.1. Символы как перечисления
В языке Pascal и в поздних версиях С есть понятие перечисляемого типа. В Ruby ничего подобного быть не может, ведь никакого контроля типов не производится. Но символы часто используются как мнемонические имена; стороны света можно было бы представить как
Быть может, немного понятнее хранить их в виде констант:
Если бы это были строки, а не символы, то определение их в виде констант могло бы сэкономить память, но каждый символ все равно существует в объектном пространстве в единственном экземпляре. (Символы, подобно объектам
6.1.2. Символы как метазначения
Мы нередко пользуемся исключениями, чтобы уйти от кодов возврата. Но никто не мешает возвращать коды ошибки, если вам так хочется. К тому же в Ruby метод может возвращать более одного значения.
В таком механизме часто возникает необходимость. Когда-то символ NUL кода ASCII вообще не считался символом. В языке С есть понятие нулевого указателя (
Проблема в том, что такие метазначения часто путают с действительными значениями. В наши дни все считают NUL настоящим символом кода ASCII. И в Ruby нельзя сказать, что
Идея в том, что иногда символы могут выступать в роли подходящих метазначений. Представьте метод, который получает строку из сети (возможно, по протоколу HTTP или иным способом). При желании можно было бы вернуть нестроковое значение как индикатор исключительной ситуации.
Можно
ли сказать, что это «лучше», чем механизм исключений? Необязательно. Но такую методику стоит иметь в виду, особенно когда приходится обрабатывать «граничные случаи», которые не считаются ошибками.6.1.3. Символы, переменные и методы
Наверное, чаще всего символы применяются для определения атрибутов класса:
Имейте в виду, что в этом фрагменте на самом деле исполняется некий код. Например,
Короче говоря, символ, передаваемый методам из семейства
В большинстве случаев (если не во всех!) методы, ожидающие на входе символ, принимают также строку. Обратное не всегда верно.
6.1.4. Преобразование строки в символ и обратно
Строки и символы можно преобразовывать друг в друга с помощью методов
Для метапрограммирования иногда бывает полезен такой метод:
Он позволяет конкатенировать символы (или дописывать строку в конец символа). Ниже приведен пример использования; мы принимаем на входе символ и пытаемся определить, представляет ли он какой-нибудь метод доступа (то есть существует ли метод чтения или установки атрибута с таким именем):
Упомяну также о более изощренном способе применения символов. Иногда при выполнении операции map нужно указать сложный блок. Однако во многих случаях мы просто вызываем некоторый метод для каждого элемента массива или набора: