Книга: Программирование на языке Ruby
6.1.4. Преобразование строки в символ и обратно
6.1.4. Преобразование строки в символ и обратно
Строки и символы можно преобразовывать друг в друга с помощью методов to_str
и to_sym
:
a = "foobar"
b = :foobar
a == b.to_str # true
b == a.to_sym # true
Для метапрограммирования иногда бывает полезен такой метод:
class Symbol
def +(other)
(self.to_s + other.to_s).to_sym
end
end
Он позволяет конкатенировать символы (или дописывать строку в конец символа). Ниже приведен пример использования; мы принимаем на входе символ и пытаемся определить, представляет ли он какой-нибудь метод доступа (то есть существует ли метод чтения или установки атрибута с таким именем):
class Object
def accessor?(sym)
return (self .respond_to?(sym) and self .respond_to?(sym+"="))
end
end
Упомяну также о более изощренном способе применения символов. Иногда при выполнении операции map нужно указать сложный блок. Однако во многих случаях мы просто вызываем некоторый метод для каждого элемента массива или набора:
list = words.map {|x| x.capitalize }
He кажется ли вам, что для такой простой задачи слишком много знаков препинания? Давайте вместо этого определим метод to_proc
в классе Symbol
. Он будет приводить любой символ к типу объекта proc
. Но какой именно объект proc
следует вернуть? Очевидно, соответствующий самому символу в контексте объекта; иными словами, такой, который пошлет сам символ в виде сообщения объекту.
def to_proc
proc {|obj, *args| obj.send(self, *args) }
end
Кстати, этот код заимствован из проекта Гэвина Синклера (Gavin Sinclair) «Расширения Ruby». Имея такой метод, мы можем следующим образом переписать первоначальный код:
list = words.map(&:capitalize)
Стоит потратить немного времени и разобраться, как это работает. Метод map
обычно принимает только блок (никаких других параметров). Наличие знака &
(амперсанд) позволяет передать объект proc
вместо явно указанного блока. Поскольку мы применяем амперсанд к объекту, не являющемуся proc, то интерпретатор пытается вызвать метод to_proc
этого объекта. Получающийся в результате объект proc подставляется вместо явного блока, чтобы метод map
вызывал его для каждого элемента массива. А зачем передавать self
в виде сообщения элементу массива? Затем, что объект proc
является замыканием и, следовательно, помнит контекст, в котором был создан. А в момент создания self
был ссылкой на символ, для которого вызывался метод to_proc
.
- 2.4. Получение длины строки
- Глава 2. Строки
- 2.28. Подсчет числа символов в строке
- 2.15. Преобразование символов в коды ASCII и обратно
- 2.10. Строки в качестве объектов ввода
- Инструмент командной строки gbak
- Инструмент командной строки gfix
- Преобразование XML в реляционную базу данных
- Миграция баз данных на Yaffil и обратно
- Режим обратной совместимости
- Имена объектов длиной 68 символов
- Эпоха символизма в копирайтинге