Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

Библиотека

generator
теперь входит в дистрибутив Ruby. Дополнительную информацию по этому вопросу вы найдете в разделе 8.3.7.

В листинге 11.15 представлена предложенная Джимом реализация генератора чисел Фибоначчи. Продолжения применяются для того, чтобы сохранить состояние между вызовами.

Листинг 11.15. Генератор чисел Фибоначчи

class Generator

 def initialize

do_generation

 end

 def next

callcc do |here|

@main_context = here;

@generator_context.call

end

 end

 private

 def do_generation

callcc do |context|

@generator_context = context;

return

end

generating_loop

 end

 def generate(value)

callcc do |context|

@generator_context = context;

@main_context.call(value)

end

 end

end

# Порождаем подкласс и определяем метод generating_loop.

class FibGenerator < Generator

 def generating_loop

generate(1)

a, b = 1, 1

loop do

generate(b)

a, b = b, a+b

end

 end

end

# Создаем объект этого класса...

fib = FibGenerator.new

puts fib.next # 1

puts fib.next # 1

puts fib.next # 2

puts fib.next # 3

puts fib.next # 5

puts fib.next # 8

puts fib.next # 13

# И так далее...

Есть, конечно, и более практичные применения продолжений. Один из примеров — каркас

Borges
для разработки Web-приложений (названный в честь Хорхе Луиса Борхеса), который построен по образу
Seaside
. В этой парадигме традиционный поток управления в Web-приложении «вывернут с изнанки на лицо», так что логика представляется «нормальной». Например, вы отображаете страницу, получаете результат из формы, отображаете следующую страницу и так далее, ни в чем не противореча интуитивным ожиданиям.

Проблема в том, что продолжение — «дорогая» операция. Необходимо сохранить состояние и потратить заметное время на переключение контекста. Если производительность для вас критична, прибегайте к продолжениям с осторожностью.

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 по-прежнему связан со старым объектом.

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

Переписка и деловые бумаги

Чехов Антон Павлович
Документальная литература:
публицистика
5.00
рейтинг книги
Переписка и деловые бумаги

Троцкий. «Демон революции»

Волкогонов Дмитрий Антонович
10 вождей
Научно-образовательная:
история
5.20
рейтинг книги
Троцкий. «Демон революции»

"Фантастика 2025-80". Компиляция. Книги 1-28

Александров Александр
Фантастика 2025. Компиляция
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Фантастика 2025-80. Компиляция. Книги 1-28

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

UNIX: взаимодействие процессов

Стивенс Уильям Ричард
Компьютеры и Интернет:
программирование
5.00
рейтинг книги
UNIX: взаимодействие процессов

Новейший философский словарь. Постмодернизм.

Грицанов Александр Алексеевич
Справочная литература:
словари
6.25
рейтинг книги
Новейший философский словарь. Постмодернизм.

Я еще князь. Книга XX

Дрейк Сириус
20. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще князь. Книга XX

Я еще не бог. Книга XXXV

Дрейк Сириус
35. Дорогой барон!
Фантастика:
аниме
попаданцы
5.00
рейтинг книги
Я еще не бог. Книга XXXV

Иллюзии

Марч Джессика
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Иллюзии

Навигаторы Апокалипсиса

Шалыгин Вячеслав Владимирович
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
Навигаторы Апокалипсиса

Осколки чести

Буджолд Лоис Макмастер
1. Сага о Форкосиганах
Фантастика:
космическая фантастика
9.34
рейтинг книги
Осколки чести

Артур и Джордж

Барнс Джулиан Патрик
Интеллектуальный бестселлер. Читает весь мир.
Детективы:
исторические детективы
6.40
рейтинг книги
Артур и Джордж

Князь Андер Арес 5

Грехов Тимофей
5. Андер Арес
Фантастика:
историческое фэнтези
фэнтези
героическая фантастика
5.00
рейтинг книги
Князь Андер Арес 5

Северянин. Трилогия

Лей Влад
Северянин
Фантастика:
фэнтези
5.75
рейтинг книги
Северянин. Трилогия