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

Фултон Хэл

Шрифт:

sym1 = :@foo

sym2 = :foo

instance_variable_set(sym1,"str") # Правильно.

instance_variable_set(sym2,"str") # Ошибка.

Короче говоря, символ, передаваемый методам из семейства

attr
, — всего лишь аргумент, а сами эти методы создают требуемые переменные и методы экземпляра, основываясь на значении символа. (В конец имени метода изменения добавляется знак равенства, а в начало имени переменной экземпляра — знак @.) Бывают также случаи, когда символ должен точно соответствовать идентификатору, на который ссылается.

В большинстве случаев (если не во всех!) методы, ожидающие на входе символ, принимают также строку. Обратное не всегда верно.

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
.

6.2. Диапазоны

Понятие диапазона интуитивно понятно, но и у него имеются некоторые неочевидные особенности и способы применения. Одним из самых простых является числовой диапазон:

digits = 0..9

scalel = 0..10

scale2 = 0...10

Оператор

..
включает конечную точку, а оператор
...
не включает. (Если это вас неочевидно, просто запомните.) Таким образом, диапазоны
digits
и
scale2
из предыдущего примера одинаковы.

Но диапазоны могут состоять не только из целых чисел — более того, не только из чисел. Началом и концом диапазона в Ruby может быть любой объект. Однако, как мы вскоре увидим, не все диапазоны осмыслены или полезны.

Основные операции над диапазоном — обход, преобразование в массив, а также выяснение, попадает ли некоторый объект в данный диапазон. Рассмотрим разнообразные варианты этих и других операций.

6.2.1. Открытые и замкнутые диапазоны

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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