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

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

Жанры

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

Стандартный итератор для любого объекта называется

each
. Это существенно отчасти из-за того, что позволяет использовать цикл
for
. Но итераторам можно давать и другие имена и применять для разных целей.

В качестве примера рассмотрим многоцелевой итератор, который имитирует цикл с проверкой условия в конце (как в конструкции

do-while
в С или
repeat-until
в Pascal):

def repeat(condition)

 yield

 retry if not condition

end

В этом примере ключевое слово

yield
служит для вызова блока, который задается при таком вызове итератора:

j=0

repeat (j >= 10) do

 j += 1

 puts j

end

С помощью

yield
можно также передать параметры, которые будут подставлены в список параметров блока (между вертикальными черточками). В следующем искусственном примере итератор всего лишь генерирует целые числа от 1 до 10, а вызов итератора порождает кубические степени этих чисел:

def my_sequence

 for i in 1..10 do

yield i

 end

end

my_sequence {|x| puts x**3 }

Отметим, что вместо фигурных скобок, в которые заключен блок, можно написать ключевые слова

do
и
end
. Различия между этими формами есть, но довольно тонкие.

1.2.7. Исключения

Как и многие другие современные языки, Ruby поддерживает исключения.

Исключения — это механизм обработки ошибок, имеющий существенные преимущества по сравнения с прежними подходами. Нам удается избежать возврата кодов ошибок и запутанной логики их анализа, а код, который обнаруживает ошибку, можно отделить от кода, который ее обрабатывает (чаще всего они так или иначе разделены).

Предложение

raise
возбуждает исключение. Отметим, что
raise
— не зарезервированное слово, а метод модуля
Kernel
. (У него есть синоним
fail
.)

raise # Пример 1

raise "Произошла ошибка" # Пример 2

raise ArgumentError # Пример 3

raise ArgumentError, "Неверные данные" # Пример 4

raise ArgumentError.new("Неверные данные ") # Пример 5

raise ArgumentError, " Неверные данные ", caller[0] # Пример 6

В первом примере повторно возбуждается последнее встретившееся исключение. В примере 2 создается исключение

RuntimeError
(подразумеваемый тип), которому передается сообщение
"Произошла ошибка"
.

В примере 3 возбуждается исключение типа

ArgumentError
, а в примере 4 такое же исключение, но с сообщением
"Неверные данные"
. Пример 5 — просто другая запись примера 4. Наконец, в примере 6 еще добавляется трассировочная информация вида
"filename:line"
или
"filename:line:in 'method'"
(хранящаяся в массиве
caller
).

А как обрабатываются исключения в Ruby? Для этой цели служит блок

begin-end
. В простейшей форме внутри него нет ничего, кроме кода:

begin

 #Ничего полезного.

 #...

end

Просто перехватывать ошибки не очень осмысленно. Но у блока может быть один или несколько обработчиков

rescue
. Если произойдет ошибка в любой точке программы между
begin
и
rescue
, то управление сразу будет передано в подходящий обработчик
rescue
.

begin

 x = Math.sqrt(y/z)

 # ...

rescue ArgumentError

 puts "Ошибка при извлечении квадратного корня."

rescue ZeroDivisionError

 puts "Попытка деления на нуль."

end

Того же эффекта можно достичь следующим образом:

begin

 x = Math.sqrt(y/z)

 # ...

rescue => err

 puts err

end

Здесь в переменной

err
хранится объект-исключение; при выводе ее на печать объект будет преобразован в осмысленную символьную строку. Отметим, что коль скоро тип ошибки не указан, то этот обработчик
rescue
будет перехватывать все исключения, производные от класса S
tandardError
. В конструкции
rescue => variable
можно перед символом
=>
дополнительно указать тип ошибки.

Если типы ошибок указаны, то может случиться так, что тип реально возникшего исключения не совпадает ни с одним из них. На этот случай после всех обработчиков

rescue
разрешается поместить ветвь
else
.

begin

 # Код, в котором может возникнуть ошибка...

rescue Type1

 # ...

rescue Type2

 # ...

else

 #Прочие исключения...

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

Воронцов. Перезагрузка. Книга 2

Тарасов Ник
2. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Воронцов. Перезагрузка. Книга 2

Второгодка. Книга 5. Презренный металл

Ромов Дмитрий
5. Второгодка
Фантастика:
городское фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Второгодка. Книга 5. Презренный металл

Локки 7. Потомок бога

Решетов Евгений Валерьевич
7. Локки
Фантастика:
аниме
эпическая фантастика
фэнтези
5.00
рейтинг книги
Локки 7. Потомок бога

Сирота

Ланцов Михаил Алексеевич
1. Помещик
Фантастика:
альтернативная история
5.71
рейтинг книги
Сирота

Лекарь Империи 10

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

Древесный маг Орловского княжества 6

Павлов Игорь Васильевич
6. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 6

На границе империй. Том 10. Часть 10

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 10

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

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

Наследие Маозари 8

Панежин Евгений
8. Наследие Маозари
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 8

Позывной "Князь"

Котляров Лев
1. Князь Эгерман
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Позывной Князь

Мастер 10

Чащин Валерий
10. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 10

Ненаглядная жена его светлости

Зика Натаэль
Любовные романы:
любовно-фантастические романы
6.23
рейтинг книги
Ненаглядная жена его светлости

Граф

Ланцов Михаил Алексеевич
6. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Граф

Вагант

Листратов Валерий
6. Ушедший Род
Фантастика:
боевая фантастика
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Вагант