Логування

Як шукати помилки у програмі та/або зрозуміти, як працює якась незрозуміла штука

У програмуванні дві проблеми:

  1. Невдале іменування змінних та функцій.

  2. Обнулили те, що не треба (чи не те, що треба).

  3. Помилка на одиницю.

Логування — це вивід у лог певної інфи, яка допоможе побачити, де порився баг.

Логи виводяться на консоль. Тому, власне, функція і називається console.log 😉

Як та що логувати?

Уявімо, у вас такий код:

let n = 10;
for(let i = 0; i >= 0; i++) {
    // тут типу якийсь код
}

Він вішає консоль, а ви не розумієте, чому. Припустімо, ви взагалі не розумієте, що відбувається. У таких випадках починайте з того, що просто логуйте всі сутності — змінні, масиви і т.д.

let n = 10;
for(let i = 0; i >= 0; i++) {
    console.log("   До коду: i = " + i + ", n = " + n);
    // тут типу якийсь код
    console.log("Після коду: i = " + i + ", n = " + n);
    console.log("---");
}

Які висновки можна зробити з цих логів?

  1. n незмінна. І в умові переривання циклу її теж нема. Проблема точно пов'язана з i.

  2. "До" та "після" не відрізняються, тобто в тілі циклу нічого корисного не відбувається.

  3. Цикл — безкінечний. Вочевидь, консоль вішається саме через це.

Щоб переконатись, залогуємо ще умову переривання циклу. І ще викинемо з консолі те, що стало зайвим (тобто n (бо вона незмінна) і розділення на "до" та "після" (бо вони однакові)).

let n = 10;
for(let i = 0; i >= 0; i++) {
    // тут типу якийсь код
    console.log("i = " + i + "\ti >= 0 == " + (i >= 0));
}

Знову переконуємось: i >= 0 завжди true. Думаємо, як вилікувати бідну програму. Можливо, так?

let n = 10;
for(let i = 0; i >= n; i++) {
    console.log("i = " + i + "\ti >= n == " + (i >= n));
    // тут типу якийсь код
}

Ура, консоль не вішається! Але й нічого не відбувається. Може це просто глюк Ш++ IDE? Знову ж, логуємо:

let n = 10;
console.log("повідомлення до циклу");
for(let i = 0; i >= n; i++) {
    console.log("i = " + i + "\ti >= n == " + (i >= n));
    // тут типу якийсь код
}
console.log("повідомлення після циклу");

Ні, це не глюк, все працює. Крім цикла. Дивимось: цикл виконується, доки i >= n. Але ж від початку i = 0, тобтоi < n вже на першій ітерації. І ми просто не заходимо в тіло цикла. Що робити? Ну, наприклад, можна просто реверснути умову:

let n = 10;
console.log("повідомлення до циклу");
for(let i = 0; i <= n; i++) {
    console.log("i = " + i);
    // тут типу якийсь код
}
console.log("повідомлення після циклу");

... або ще якось, залежно від умов задачі. У будь-якому разі, все запрацювало.

Приблизно так і виглядає логування. Виводимо на консоль інфу та шукаємо проблему. Звучить доволі просто :)

Висновок

Логування — це круто і допомагає. Але писати код навмання — максимально непродуктивно.

Ніж розгрібати купу багів, варто від самого початку розуміти, що відбуватиметься на кожному кроці програми. Причому розуміти ще до того, як її запустимо. Треба будувати алгоритм на папері (буквально: беремо аркуш зошита і там пишемо / малюємо) та "запускати код в голові", передбачувати дії програми до появи багів, щоб їх і не виникало взагалі.

Спочатку це буде складно, але з кожною новою задачею дедалі простішатиме. Тому пишіть код руками не рідше, ніж читаєте теорію — і буде вам щастя :)

Last updated