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

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

Жанры

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

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

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

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Первый среди равных. Книга III

Бор Жорж
3. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
6.00
рейтинг книги
Первый среди равных. Книга III

Эпоха Опустошителя. Том I

Павлов Вел
1. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том I

Кодекс Крови. Книга ХVIII

Борзых М.
18. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVIII

Гезат

Чернобровкин Александр Васильевич
22. Вечный капитан
Фантастика:
альтернативная история
5.25
рейтинг книги
Гезат

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

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

Бродяга

Первухин Андрей Евгеньевич
1. Бродяга
Фантастика:
попаданцы
5.40
рейтинг книги
Бродяга

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

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

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

Школа пластунов

Трофимов Ерофей
Одиночка
Фантастика:
боевая фантастика
5.00
рейтинг книги
Школа пластунов

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

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

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

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

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Распутье

Басаргин Иван Ульянович
Сибириада
Проза:
военная проза
историческая проза
5.00
рейтинг книги
Распутье