У цьому розділі більше поговоримо про керуючі структури в Ruby.
справа
Ми використовуємо оператор case для перевірки послідовності умов. Це дійсно дуже схоже на switch у C та Java, але є більш потужним інструментом, як ми побачимо далі.
ruby> i=8 ruby> case i | when 1, 2..5 | print "1..5\n" | when 6..10 | print "6..10\n" | end 6..10 nil
2..5 є виразом, який означає діапазон між 2 і 5, включно. Наступний вираз перевіряє, що значення i лежить у цьому діапазоні:
(2..5) === i
case внутрішньо використовує взаємовідносини з оператором === для перевірки кількох умов за раз. Для збереження об'єктно-орієнтованої природи в ruby оператор === інтерпретується залежно від об'єкта, який порівнюється з умовою в when операторі. Наприклад, наступний код порівнює рядки у першому операторі when, і з регулярним виразом у другому операторі when .
ruby> case 'abcdef' | when 'aaa', 'bbb' | print "aaa or bbb\n" | when /def/ | print "includes /def/\n" | end includes /def/ nil
поки
Ruby надає кілька способів для створення керуючих циклів, хоча ви знайдете в наступному розділі, як використовувати ітератори, щоб не використовувати звичайні цикли занадто часто.
While є повторюваним if. Ми використовували цей цикл у програмах для загадок і регулярних виразів (ви можете звернутися до попереднього розділу ). Отже, цей цикл складається з оператора while, умови тіла циклу та оператора end. Тіло циклу оброблятиметься доти, доки умова повертатиме true . Але при цьому while може легко застосовуватися і до окремих рядків коду, і тоді оператор end не потрібно.
ruby> i = 0 0 ruby> print "It's zero.\n" if i==0 It's zero. nil ruby> print "It's negative.\n" if i<0 nil ruby> print "#{i+=1}\n" while i<3 1 2 3 nil
Іноді ви можете захотіти перевірку з негативним результатом. unless є протилежним варіантом if , і until є протилежним варіантом while. Ми залишимо вас для експериментів із цими операторами.
Є кілька способів переривання проходження циклу зсередини. По-перше, break , який має значення, що у C, для виходу з петлі. По-друге, next для запуску наступної ітерації циклу (C це continue ). По-третє, ruby має redo, котрий перезапускає поточну ітерацію. Наступний код на ілюструє значення break, next і redo.
while (condition) { label_redo: goto label_next; /* ruby's "next" */ goto label_break; /* ruby's "break" */ goto label_redo; /* ruby's "redo" */ ... ... label_next: } label_break: ...
Четвертим способом виходу із петлі є оператор return, усередині циклу. Але виконання return викликає не тільки вихід із циклу, а й вихід із методу, який містить цей цикл. Якщо заданий аргумент, то оператор поверне значення з методу, що викликається, в іншому випадку буде повернутий nil.
для
З програмістам буде цікаво дізнатися, як можна використовувати цикл * for *. У Ruby це робиться трохи цікавішим. Цикл, представлений нижче, запускається кожного разу для кожного елемента в колекції:
for elt in collection ... end
Колекція може бути діапазоном значень (це те, що має на увазі більшість людей, коли вони говорять про цикл):
ruby> for num in (4..6) | print num,"\n" | end 4 5 6 4..6
Це може бути колекція іншого виду, наприклад масив:
ruby> for elt in [100,-9.6,"pickle"] | print "#{elt}\t(#{elt.type})\n" | end 100 (Fixnum) -9.6 (Float) pickle (String) [100, -9.6, "pickle"]
Але ми забігаємо трохи вперед. for має ще інший спосіб запису з методом each , як виявилося, і який розглянемо в першому прикладі з ітератором. Наступні дві форми будуть еквівалентними:
# Если вы использовали C или Java, то предпочитаете скорее всего такой стиль for i in collection ... end # Smalltalk программисты могут предпочитать такой стиль collection.each {|i| ... }
Ітератори часто можуть бути замінені на відповідні цикли, але як тільки ви почнете використовувати їх, ви зрозумієте, що роботи з ними справді легші.