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 с модификаторами. Они довольно часто используются из-за краткости. Вот еще два примера, в которых делается одно и то же:

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату