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

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

Жанры

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

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

Советник 2

Шмаков Алексей Семенович
7. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Советник 2

Дитя прибоя

Трофимов Ерофей
Дитя прибоя
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Дитя прибоя

Клод Моне

де Декер Мишель
1034. Жизнь замечательных людей
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Клод Моне

Мой муж – чудовище! Изгнанная жена дракона

Терин Рем
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мой муж – чудовище! Изгнанная жена дракона

Камень. Книга пятая

Минин Станислав
5. Камень
Фантастика:
боевая фантастика
6.43
рейтинг книги
Камень. Книга пятая

Я все еще не князь. Книга XV

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

Последний Герой. Том 4

Дамиров Рафаэль
Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 4

Аспирант

Поселягин Владимир Геннадьевич
3. Рунный маг
Фантастика:
боевая фантастика
4.50
рейтинг книги
Аспирант

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Мы - истребители

Поселягин Владимир Геннадьевич
2. Я - истребитель
Фантастика:
альтернативная история
8.55
рейтинг книги
Мы - истребители

Я - злодейка в дораме. Сезон второй

Вострова Екатерина
2. Выжить в дораме
Фантастика:
уся
фэнтези
сянься
попаданцы
5.00
рейтинг книги
Я - злодейка в дораме. Сезон второй

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

Моров. Том 5

Кощеев Владимир
4. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 5