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

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

Жанры

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

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

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

Имперец. Том 4

Романов Михаил Яковлевич
3. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 4

Изгой

Майерс Александр
2. Династия
Фантастика:
фэнтези
попаданцы
рпг
аниме
5.00
рейтинг книги
Изгой

Точка Бифуркации IV

Смит Дейлор
4. ТБ
Фантастика:
героическая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации IV

Мое ускорение

Иванов Дмитрий
5. Девяностые
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Мое ускорение

Законы Рода. Том 2

Андрей Мельник
2. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 2

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Последний Паладин. Том 13

Саваровский Роман
13. Путь Паладина
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 13

Мусорщик - 2. Проводник Теней

Лазарь
2. Хозяин Теней
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Мусорщик - 2. Проводник Теней

Травница Его Драконейшества

Рель Кейлет
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Травница Его Драконейшества

Личный аптекарь императора. Том 5

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

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Ермак. Противостояние. Книга одиннадцатая

Валериев Игорь
11. Ермак
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Ермак. Противостояние. Книга одиннадцатая

ЖЛ 9

Шелег Дмитрий Витальевич
9. Живой лёд
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
ЖЛ 9

День Астарты

Розов Александр Александрович
6. Конфедерация Меганезия
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
День Астарты