Evgenii Legotckoi
Evgenii Legotckoi23 червня 2016 р. 02:01

Посібник користувача №07 - Ruby - Повернення до простих прикладів

А тепер давайте розберемо код із деяких наших попередніх прикладів програм.

Наступний приклад з'явився вперше в цьому розділі (https://evileg.com/ru/post/115/) .

def fact(n)
  if n == 0
    1
  else
    n * fact(n-1)
  end
end
print fact(ARGV[0].to_i), "\n"

Оскільки це перше пояснення, то розглянемо кожен рядок окремо.


Факторіал

def fact(n)

У першому рядку оператор def оголошує функцію (або, точніше, метод , ми поговоримо про методи в іншому розділі). Тут це вказує функцію fact, яка приймає один аргумент, описаний як n .

if n == 0

Далі перевірка умови. Коли умова виконується, тоді виконується код, наступний за умовою, інакше виконується код, що настає else .

1

Значення, що повертається, якщо умова виконалася.

else

Якщо умова не виконалася, то цей шматок коду виконується до оператора end.

n * fact(n-1)

Якщо умова не виконалося, то результатом є n якраз виконання функції факторіалу fact(n-1).

end

Перший оператор end, який закриває оператор if.

end

Другий оператор end, що закриває тіло функції, тобто оператор def .

print fact(ARGV[0].to_i), "\n"

Викликаємо функцію факторіалу fact() , використовуючи значення, передане в командний рядок і виводимо результат.

ARGV є масивом, який містить аргументи командного рядка. Елементи ARGV є рядками, тому ми повинні конвертувати їх у цілісний тип за допомогою методу *to_i. Ruby не перетворює рядки в цілісні типи автоматично, як це робить Perl.

Строки

Наступний приклад був показаний у розділі про рядки (https://evileg.com/ru/post/116/).

words = ['foobar', 'baz', 'quux']
secret = words[rand(3)]

print "guess? "
while guess = STDIN.gets
  guess.chop!
  if guess == secret
    print "you win\n"
    break
  else
    print "you lose.\n"
  end
  print "guess? "
end
print "the word is ", secret, ".\n"

У цій програмі є нова структура з умовою, це цикл while. Код між while та його відповідним оператором end буде виконуватися доти, доки виконується умова циклу.

rand(3) у рядку 2 повертає випадкове число в діапазоні від 0 до 2. Це випадкове число використовується для вилучення одного з трьох слів у масиві words .

У рядку 5 зчитується рядок зі стандартного введення STDIN.gets. Якщо отримано EOF (кінець файлу), gets повертає nil . Таким чином код повторюватиметься доти, доки не отримає комбінацію завершення D* (або * Z підDOS).

guess.chop! у рядку 6 видаляється останні символи зі змінної guess . У цьому випадку це завжди означає новий рядок.

У рядку 15 виводиться таємне слово. Ми маємо оператор print з трьома аргументами (які виводяться один за одним), але також ефективно, якби працювали з одним аргументом, записуючи secret як #{secret}, щоб було ясно, що це змінна, а не рядок для висновку:

print "the word is #{secret}.\n"

Регулярні вирази

І насамкінець розглянемо програму з розділу по регулярним виразам .

st = "\033[7m"
en = "\033[m"

while TRUE
  print "str> "
  STDOUT.flush
  str = gets
  break if not str
  str.chop!
  print "pat> "
  STDOUT.flush
  re = gets
  break if not re
  re.chop!
  str.gsub! re, "#{st}\\&#{en}"
  print str, "\n"
end
print "\n"

У рядку 4 умова циклу while встановлено в true. Таким чином зроблено нескінченний цикл. Однак у рядках 8 та 13 доданий оператор break для виходу з циклу. Ці два оператори break також є прикладом модифікації if . Модифікація if виконує оператор з лівого боку, лише якщо умова виконується.

Є кілька слів про метод chop! (див. рядки 9 та 14). У Ruby ми додаємо символи '!' або '?' наприкінці імен методів. Знак оклику (!, іноді вимовляється як "бах!") вказує на те, що метод є потенційно руйнівним і може змінити значення, якого стосується. chop! безпосередньо впливає на рядок, але просто chop без знака оклику працює як копіювання. У цьому полягає відмінність.

ruby> s1 = "forth"
  "forth"
ruby> s1.chop!       # This changes s1.
  "fort"
ruby> s2 = s1.chop   # This puts a changed copy in s2,
  "for"
ruby> s1             # ... without disturbing s1.
  "fort"

Ви пізніше зіткнетеся з методом на кінці якого буде застосовуватись знак питання (?, Іноді вимовляється як "huh?"); який вказує що метод є предикатом, тобто повертає значення між true і false.

Рядок 15 заслуговує на пильну увагу. По-перше це метод gsub!, який є деструктивним методом. Він змінює змінну str, замінюючи всі символи, які збігаються з шаблоном re ( sub означає заміну, а символ g попереду означає глобальний вплив, тобто заміна всіх частин, що збіглися в рядку, а не тільки перший знайдений шматок ). Отже, все йде нормально, але що ми замінюємо у цьому тексті? st та en визначені в 1 та 2 рядках, як ANSI послідовності, які роблять текст нормальний та інвертований. У рядку 15 вони поміщені в #{} , щоб переконатися, що вони справді інтерпретуються як треба, а чи не як рядки висновку. Між ними бачимо послідовність "\&" . Це невеликий трюк. Так як заміна здійснюється в подвійних лапках, то пара зворотних слешів інтерпретуватиметься як "\&". В результаті буде надруковано новий рядок, схожий на старий, за винятком того, що будуть підсвічені ті частини, які збіглися з шаблоном.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50бали,
  • Рейтинг балів-4
m
  • molni99
  • 26 жовтня 2024 р. 08:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
m
  • molni99
  • 26 жовтня 2024 р. 08:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20бали,
  • Рейтинг балів-10
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 19:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 21:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 15:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 14:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 18:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 22:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 листопада 2024 р. 14:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject04 червня 2022 р. 10:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9Anonim25 жовтня 2024 р. 16:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Слідкуйте за нами в соціальних мережах