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

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

Жанры

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

Здесь формы с ключевыми словами

if
и
unless
, расположенные в одной строке, выполняют в точности одинаковые функции. Обратите внимание, что слово
then
можно опускать во всех случаях, кроме последнего (предназначенного для использования в выражениях). Также заметьте, что в модификаторах (третья строка) ветви
else
быть не может.

Предложение

case
в Ruby позволяет больше, чем в других языках. В его ветвях можно проверять различные условия, а не только сравнивать на равенство. Так, например, разрешено сопоставление с регулярным выражением. Проверки в предложении
case
эквивалентны оператору ветвящегося равенства (
===
), поведение которого
зависит от объекта. Рассмотрим пример:

case "Это строка символов."

 when "одно значение"

puts "Ветвь 1"

 when "другое значение"

puts "Ветвь 2"

 when /симв/

puts "Ветвь 3"

 else

puts "Ветвь 4"

end

Этот код напечатает

Ветвь 3
. Почему? Сначала проверяемое выражение сравнивается на равенство с двумя строками:
"одно значение"
и
"другое значение"
. Эта проверка завершается неудачно, поэтому мы переходим к третьей ветви. Там находится образец, с которым сопоставляется выражение. Поскольку оно соответствует образцу, то выполняется предложение
print
. В ветви
else
обрабатывается случай, когда ни одна из предшествующих проверок не прошла.

Если проверяемое выражение — целое число, то его можно сравнивать с целочисленным диапазоном (например,

3..8
); тогда проверяется, что число попадает в диапазон. В любом случае выполняется код в первой подошедшей ветви.

В Ruby имеется богатый набор циклических конструкций. К примеру,

while
и
until
— циклы с предварительной проверкой условия, и оба работают привычным образом: в первом случае задается условие продолжения цикла, а во втором — условие завершения. Есть также их формы с модификатором, как для предложений
if
и
unless
. Кроме того, в модуле
Kernel
есть метод
loop
(по умолчанию бесконечный цикл), а в некоторых классах реализованы итераторы.

В примерах из таблицы 1.2 предполагается, что где-то определен такой массив

list
:

list = %w[alpha bravo charlie delta echo];

В цикле этот массив обходится и печатается каждый его элемент.

Таблица 1.2. Циклы

# Цикл 1 (while) # Цикл 2 (until)
i=0 while i < list.size do print "#{list[i]} " i += 1 end
i=0 until i == list.size do print "#{list[i]} " i += 1 end
# Цикл 3 (for) # Цикл 4 (итератор 'each')
for x in list do print "#{x} " end
list.each do |x| print "#{x} " end
# Цикл 5 (метод 'loop') # Цикл 6 (метод 'loop')
i = 0 n=list.size-1 loop do print "#{list[i]} " i += 1 break if i > n end
i=0 n=list.size-1 loop do print "#{list[i]} " i += 1 break unless i <= n end
# Цикл 7 (итератор 'times') # Цикл 8 (итератор 'upto')
n=list.size n.times do |i| print "#{list[i]} " end
n=list.size-1 0.upto(n) do |i| print "#{list[i]} " end
# Цикл 9 (for) # Цикл 10 ('each_index')
n=list.size-1 for i in 0..n do print "#{list[i]} " end
list.each_index do |x| print "#{list[x]} " end

Рассмотрим

эти примеры более подробно. Циклы 1 и 2 — «стандартные» формы циклов
while
и
until
; ведут они себя практически одинаково, только условия противоположны. Циклы 3 и 4 — варианты предыдущих с проверкой условия в конце, а не в начале итерации. Отметим, что использование слов
begin
и
end
в этом контексте — просто грязный трюк; на самом деле это был бы блок begin/end (применяемый для обработки исключений), за которым следует модификатор
while
или
until
. Однако для тех, кто желает написать цикл с проверкой в конце, разницы нет.

На мой взгляд, конструкции 3 и 4 — самый «правильный» способ кодирования циклов. Они заметно проще всех остальных: нет ни явной инициализации, ни явной проверки или инкремента. Это возможно потому, что массив «знает» свой размер, а стандартный итератор

each
(цикл 6) обрабатывает такие детали автоматически. На самом деле в цикле 5 производится неявное обращение к этому итератору, поскольку цикл
for
работает с любым объектом, для которого определен итератор
each
. Цикл
for
— лишь сокращенная запись для вызова
each
; часто такие сокращения называют «синтаксической глазурью», имея в виду, что это не более чем удобная альтернативная форма другой синтаксической конструкции.

В циклах 5 и 6 используется конструкция

loop
. Выше мы уже отмечали, что хотя
loop
выглядит как ключевое слово, на самом деле это метод модуля
Kernel
, а вовсе не управляющая конструкция.

В циклах 7 и 8 используется тот факт, что у массива есть числовой индекс. Итератор

times
исполняется заданное число раз, а итератор
upto
увеличивает свой параметр до заданного значения. И тот, и другой для данной ситуации приспособлены плохо.

Цикл 9 — это вариант цикла

for
, предназначенный специально для работы со значениями индекса при помощи указания диапазона. В цикле 10 мы пробегаем весь диапазон индексов массива с помощью итератора
each_index
.

В предыдущих примерах мы уделили недостаточно внимания вариантам циклов

while
и
loop
с модификаторами. Они довольно часто используются из-за краткости. Вот еще два примера, в которых делается одно и то же:

perform_task until finished

perform_task while not finished

Также из таблицы 1.2 осталось неясным, что циклы не всегда выполняются от начала до конца. Число итераций не всегда предсказуемо. Нужны дополнительные средства управления циклами.

Первое из них — ключевое слово

break
, встречающееся в циклах 5 и 6. Оно позволяет досрочно выйти из цикла; в случае вложенных циклов происходит выход из самого внутреннего. Для программистов на С это интуитивно очевидно.

Ключевое слово

retry
применяется в двух случаях: в контексте итератора и в контексте блока
begin-end
(обработка исключений). В теле итератора (или цикла
for
) оно заставляет итератор заново выполнить инициализацию, то есть повторно вычислить переданные ему аргументы. Отметим, что к циклам общего вида это не относится.

Ключевое слово

redo
— обобщение
retry
на циклы общего вида. Оно работает в циклах
while
и
until
, как
retry
в итераторах.

Ключевое слово

next
осуществляет переход на конец самого внутреннего цикла и возобновляет исполнение с этой точки. Работает для любого цикла и итератора.

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

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

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Мастер 10

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

Новик

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

Моя простая курортная жизнь 5

Блум М.
5. Моя простая курортная жизнь
Любовные романы:
эро литература
5.00
рейтинг книги
Моя простая курортная жизнь 5

Темные тропы и светлые дела

Владимиров Денис
3. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Темные тропы и светлые дела

Зеркало силы

Кас Маркус
3. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Зеркало силы

Мастер...

Чащин Валерий
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Мастер...

Я – Легенда 2: геном хищника

Гарцевич Евгений Александрович
2. Я - Легенда!
Фантастика:
боевая фантастика
рпг
фантастика: прочее
попаданцы
5.00
рейтинг книги
Я – Легенда 2: геном хищника

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

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

Я все еще князь. Книга XXI

Дрейк Сириус
21. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще князь. Книга XXI

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл

Графиня с изъяном. Тайна живой стали

Лин Айлин
Фантастика:
фэнтези
героическая фантастика
киберпанк
5.00
рейтинг книги
Графиня с изъяном. Тайна живой стали

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Орден Архитекторов 12

Винокуров Юрий
12. Орден Архитекторов
Фантастика:
фэнтези
5.00
рейтинг книги
Орден Архитекторов 12