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

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

Жанры

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

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

Тринадцатый IV

NikL
4. Видящий смерть
Фантастика:
боевая фантастика
попаданцы
6.25
рейтинг книги
Тринадцатый IV

Тарзан (Сборник рассказов)

Берроуз Эдгар Райс
Тарзан
Приключения:
природа и животные
7.80
рейтинг книги
Тарзан (Сборник рассказов)

История ислама. Исламская цивилизация от рождения до наших дней

Ходжсон Маршалл Гудвин Симмс
Научно-образовательная:
история
культурология
религиоведение
4.00
рейтинг книги
История ислама. Исламская цивилизация от рождения до наших дней

Петербург - нуар. Рассказы

Кивинов Андрей Владимирович
Проза:
современная проза
5.40
рейтинг книги
Петербург - нуар. Рассказы

Гильдия

Голотвина Ольга Владимировна
Гильдия
Фантастика:
боевая фантастика
5.25
рейтинг книги
Гильдия

Арестант

Константинов Андрей Дмитриевич
7. Бандитский Петербург
Детективы:
боевики
8.29
рейтинг книги
Арестант

Эзотерический мир. Семантика сакрального текста

Розин Вадим Маркович
Религия и эзотерика:
эзотерика
5.00
рейтинг книги
Эзотерический мир. Семантика сакрального текста

Виконт. Книга 2. Обретение силы

Юллем Евгений
2. Псевдоним `Испанец`
Фантастика:
боевая фантастика
попаданцы
рпг
7.10
рейтинг книги
Виконт. Книга 2. Обретение силы

Атосса. Император

Эберс Георг Мориц
Проза:
историческая проза
5.00
рейтинг книги
Атосса. Император

Я снова царь. Книга XXXIII

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

Город золотых теней

Уильямс Тэд
1. Иноземье
Фантастика:
научная фантастика
7.00
рейтинг книги
Город золотых теней

Лето ночи

Симмонс Дэн
1. Ночь
Детективы:
триллеры
8.44
рейтинг книги
Лето ночи

Ипатия

Кингсли Чарльз
Проза:
историческая проза
5.00
рейтинг книги
Ипатия

Аромалогия. Quantum Satis

Миргородская Светлана
Дом и Семья:
здоровье и красота
6.60
рейтинг книги
Аромалогия. Quantum Satis