Ошибки
Ошибки — это нормальная часть программирования. Даже опытные разработчики сталкиваются с ними каждый день. Разница между новичком и профессионалом не в том, что один не допускает ошибок, а в том, что другой умеет быстро их находить и исправлять.
Три типа ошибок
Синтаксические ошибки
Программа не запустилась вообще — интерпретатор не смог прочитать код. Как если бы ты написал предложение с неправильной грамматикой — оно непонятно.
Такие ошибки CraftOS обнаруживает до запуска и сразу показывает в какой строке проблема.
Ошибки времени выполнения (Runtime errors)
Программа запустилась, но упала во время работы. Синтаксис правильный, но что-то пошло не так в процессе.
Логические ошибки
Программа запускается и работает без ошибок — но делает не то что нужно. Самый коварный тип: компьютер не знает что что-то не так.
Как читать сообщение об ошибке
Когда программа падает, CraftOS выводит сообщение такого вида:
my_program:7: attempt to perform arithmetic on a nil value (global 'fuel')
Разбираем по частям:
| Часть | Значение |
|---|---|
my_program | Имя файла где произошла ошибка |
:7 | Номер строки |
attempt to perform arithmetic on a nil value | Описание ошибки |
(global 'fuel') | Какая переменная оказалась nil |
Первым делом смотри на номер строки и открывай файл на этой строке.
Частые ошибки в Lua и как их исправить
attempt to perform arithmetic on a nil value
Ты пытаешься делать математику с переменной, которая равна nil:
Или переменная есть, но функция вернула nil вместо числа:
attempt to concatenate a nil value
Ты пытаешься склеить строку через .. с переменной, которая равна nil:
attempt to index a nil value
Ты пытаешься обратиться к полю или методу у переменной, которая равна nil:
stack overflow
Функция вызывает саму себя бесконечно (бесконечная рекурсия):
Too long without yielding
Цикл работает слишком долго без паузы. Решение — добавить sleep():
Как искать ошибки: отладка через print
Самый простой способ понять что происходит внутри программы — добавить временные print:
Когда нашёл ошибку — удали или закомментируй отладочные строки.
Удобно обернуть в флаг:
Как поймать ошибку программно: pcall
Иногда нужно перехватить ошибку и продолжить работу вместо падения. Для этого — pcall (protected call):
Пример с черепашкой — если GPS недоступен, не падаем:
pcall принимает функцию и её аргументы:
Чеклист при ошибке
Когда программа упала, делай по порядку:
- Прочитай сообщение об ошибке — оно говорит точно что пошло не так и где
- Открой файл на указанной строке —
edit my_program, перейди к нужной строке - Проверь переменные рядом с этой строкой — не равна ли какая-то из них
nil? - Добавь
printперед строкой с ошибкой — выведи значения всех переменных - Проверь откуда приходят данные — функция вернула то что ты ожидал?
- Гугли текст ошибки —
attempt to index a nil value luaдаст тысячи объяснений
🚀 Задания
Задание 1 Запусти эти программы по одной, прочитай сообщение об ошибке и объясни что в каждой пошло не так:
Задание 2
Напиши функцию safeDivide(a, b), которая делит a на b. Если b равно 0 — не падает с ошибкой, а возвращает nil и сообщение "Деление на ноль". Проверь с разными значениями.
Задание 3
Добавь систему отладки с флагом DEBUG в любую свою программу из прошлых уроков. Убедись, что при DEBUG = false лишние сообщения не выводятся.
Задание 4
Напиши программу, которая читает строку через read() и пытается преобразовать её в число через tonumber(). Если пользователь ввёл не число (tonumber вернёт nil) — выведи ошибку и попроси ввести снова. Повторяй пока не получишь число.
Задание 5
Используй pcall чтобы обернуть вызов gps.locate(). Если функция упала или вернула nil — выведи сообщение что GPS недоступен. Если успешно — выведи координаты.