Книга: Программирование на языке Ruby
11.2.6. Хранение кода в виде объекта
11.2.6. Хранение кода в виде объекта
Неудивительно, что Ruby предлагает несколько вариантов хранения фрагмента кода в виде объекта. В этом разделе мы рассмотрим объекты Proc
, Method
и UnboundMethod
.
Встроенный класс Proc
позволяет обернуть блок в объект. Объекты Proc
, как и блоки, являются замыканиями, то есть запоминают контекст, в котором были определены.
myproc = Proc.new { |a| puts "Параметр равен #{а}" }
myproc.call(99) # Параметр равен 99
Кроме того, Ruby автоматически создает объект Proc, когда метод, последний параметр которого помечен амперсандом, вызывается с блоком в качестве параметра:
def take_block(x, &block)
puts block.class
x.times {|i| block[i, i*i] }
end
take_block(3) { |n,s| puts "#{n} в квадрате равно #{s}" }
В этом примере демонстрируется также применение квадратных скобок как синонима метода call
. Вот что выводится в результате исполнения:
Proc
0 в квадрате 0
1 в квадрате 1
2 в квадрате 4
Объект Proc
можно передавать методу, который ожидает блок, предварив имя знаком &
:
myproc = proc { |n| print n, "... " }
(1..3).each(&myproc) # 1... 2... 3...
Ruby позволяет также превратить метод в объект. Исторически для этого применяется метод Object#method
, который создает объект класса Method
как замыкание в конкретном объекте.
str = "cat"
meth = str.method(:length)
a = meth.call # 3 (длина "cat")
str << "erpillar"
b = meth.call # 11 (длина "caterpillar")
str = "dog"
# Обратите внимание на следующий вызов! Переменная str теперь ссылается
# на новый объект ("dog"), но meth по-прежнему связан со старым объектом.
с = meth.call # 11 (длина "caterpillar")
Начиная с версии Ruby 1.6.2, можно также применять метод Module#instance_method
для создания объектов UnboundMethod
. С их помощью представляется метод, ассоциированный с классом, а не с конкретным объектом. Прежде чем вызывать объект UnboundMethod
, нужно связать его с каким-то объектом. Результатом операции связывания является объект Method
, который можно вызывать как обычно:
umeth = String.instance_method(:length)
m1 = umeth.bind("cat")
m1.call # 3
m2 = umeth.bind("caterpillar")
m2.call # 11
Явное связывание делает объект UnboundMethod
интуитивно более понятным, чем Method
.
- 11.2.1. Отправка объекту явного сообщения
- 11.2.2. Специализация отдельного объекта
- 11.2.3. Вложенные классы и модули
- 11.2.4. Создание параметрических классов
- 11.2.5. Использование продолжений для реализации генератора
- 11.2.6. Хранение кода в виде объекта
- 11.2.7. Как работает включение модулей?
- 11.2.8. Опознание параметров, заданных по умолчанию
- 11.2.9. Делегирование или перенаправление
- 11.2.10. Автоматическое определение методов чтения и установки на уровне класса
- 11.2.11. Поддержка различных стилей программирования
- 9.4.1. Реализация графа в виде матрицы смежности
- Сохранение информации о пользователях при миграции
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Сохранение информации из Интернета
- Глава 5 Агрессивные формы кода и борьба с ними
- Хранение конфигурации в системном реестре
- Глава 15 Редактирование музыки и видео
- Стиль написания исходного кода
- Сохранение рабочей книги с именем, представляющим собой текущую дату
- 6.8. Разгон видеокарты на Windows 10
- Видеопамять
- Сохранение и использование шаблона узла