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

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

Жанры

Программирование на языке 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

INDIGO
5. Отпуск
Фантастика:
космическая фантастика
фантастика: прочее
5.67
рейтинг книги
Третий. Том 5

Под знаком Песца

Видум Инди
1. Под знаком Песца
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Под знаком Песца

Max War

Ядов Алексей Дмитриевич
5.00
рейтинг книги
Max War

Черный лебедь. Тетралогия

Мид Райчел
Черный Лебедь
Фантастика:
фэнтези
ужасы и мистика
детективная фантастика
8.74
рейтинг книги
Черный лебедь. Тетралогия

Моров. Том 1 и Том 2

Кощеев Владимир
1. Моров
Фантастика:
попаданцы
альтернативная история
аниме
5.25
рейтинг книги
Моров. Том 1 и Том 2

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

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

Арестант

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

Битва королей

Мартин Джордж Р.Р.
2. Песнь Льда и Огня
Фантастика:
фэнтези
9.61
рейтинг книги
Битва королей

История любовная

Шмелев Иван Сергеевич
Проза:
классическая проза
6.25
рейтинг книги
История любовная

Ночь с Ангелом

Кунин Владимир Владимирович
Проза:
современная проза
7.43
рейтинг книги
Ночь с Ангелом

Газлайтер. Том 22

Володин Григорий Григорьевич
22. История Телепата
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.25
рейтинг книги
Газлайтер. Том 22

Кысь. Зверотур. Рассказы

Толстая Татьяна Никитична
Проза:
проза прочее
5.00
рейтинг книги
Кысь. Зверотур. Рассказы

Костер на снегу

Райан Нэн
Любовные романы:
исторические любовные романы
7.00
рейтинг книги
Костер на снегу

Невеста Дерини

Куртц Кэтрин Ирен
4. Хроники короля Келсона
Фантастика:
фэнтези
7.14
рейтинг книги
Невеста Дерини