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

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

Жанры

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

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

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

Тигриный лог

Чеснокова Юлия Олеговна
Детективы:
прочие детективы
7.00
рейтинг книги
Тигриный лог

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Кодекс Охотника. Книга XXVII

Винокуров Юрий
27. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXVII

Франкенштейн: Антология

Шелли Мэри
1. Лучшее
Фантастика:
социально-философская фантастика
научная фантастика
ужасы и мистика
7.43
рейтинг книги
Франкенштейн: Антология

"Фантастика 2025-124". Компиляция. Книги 1-22"

Царицын Владимир
Фантастика 2025. Компиляция
Фантастика:
боевая фантастика
попаданцы
мистика
5.00
рейтинг книги
Фантастика 2025-124. Компиляция. Книги 1-22

Защитник

Кораблев Родион
11. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Защитник

Хроники былого и грядущего

allig_eri
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Хроники былого и грядущего

Трапеция

Брэдли Мэрион Зиммер
Проза:
современная проза
5.00
рейтинг книги
Трапеция

Имаджика

Баркер Клайв
7. Книга-загадка, книга-мистика
Фантастика:
фэнтези
7.56
рейтинг книги
Имаджика

Распутин

Наживин Иван Федорович
Проза:
историческая проза
5.00
рейтинг книги
Распутин

Лекарь

Назимов Константин Геннадьевич
2. Травник
Фантастика:
фэнтези
5.25
рейтинг книги
Лекарь

Романов. Том 1 и Том 2

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

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

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

Смерть в сновидениях

Ноар Кейла
Религия и эзотерика:
эзотерика
5.00
рейтинг книги
Смерть в сновидениях