Эта справочная страница, Help:Lua debugging , объясняет проблемы написания скрипта Lua и отладки исходного кода , для устранения ошибок или повышения производительности. Поскольку Lua является «полукомпилированным» интерпретируемым языком, он не выполняет предварительную проверку на все распространенные синтаксические ошибки и не обнаруживает неправильно написанные переменные, которые обнаруживаются только во время выполнения при появлении сообщения « Script error ». Кроме того, в отличие от wp:templates , которые можно запустить интерактивно с помощью edit-preview, скрипт Lua должен быть протестирован с помощью show-preview (или run preview) другой страницы, которая использует шаблон, который #invoke
является редактируемым модулем Lua. В общем, делайте одно небольшое изменение за раз, запускайте show-preview и сохраняйте после нескольких хороших изменений, чтобы иметь версию для восстановления, на случай возникновения ужасных ошибок после многочисленных последующих изменений. Примечание: сохранение рабочей копии можно выполнить в автономном текстовом файле, а не сохранять каждую версию в ревизиях модуля.
Другие предварительно скомпилированные или полукомпилированные языки могут точно определить номер строки или кодовую фразу, где обнаружена синтаксическая ошибка или неопределенное имя переменной; однако эта обработка может потребовать дополнительного времени для выполнения. Вместо этого можно использовать инструмент лексического анализа , специально для скрипта Lua, чтобы лучше обнаруживать и точно определять неправильно написанные переменные или логические ошибки в исходном коде Lua.
Изменения в модулях Lua в реальном времени можно протестировать во время редактирования в качестве предварительного просмотра, используя новую опцию предварительного просмотра для шаблонов/модулей, чтобы «Показать предварительный просмотр» страницы, которая использует шаблон/модуль. В противном случае модули Lua нельзя запустить интерактивно для просмотра результатов, что является функцией только в шаблонах на основе разметки. Вместо этого модули Lua обычно редактируются, сохраняются и запускаются (вызывающим шаблоном), чтобы увидеть, могут ли какие-либо синтаксические ошибки быть обнаружены полукомпиляцией во время сохранения редактирования. Между тем, хотя предварительный просмотр запуска не будет сообщать о простых синтаксических ошибках, он позволяет редактировать модуль в реальном времени, а затем выбирать «Показать предварительный просмотр» вызывающей страницы, чтобы увидеть результаты или если «Ошибка сценария» возникает во время предварительного просмотра запуска, много раз, перед фактическим сохранением редактирования. Однако сохранение редактирования дает преимущество в виде просмотра некоторых сообщений полукомпиляции для проверки простых синтаксических ошибок, таких как дублирование «then then», которые не будут сообщены во время предварительного просмотра показа.
Может быть много причин, по которым модуль Lua вызывает сообщение « Ошибка скрипта » при запуске на другой странице. При щелчке по тексту ошибки отображается всплывающее окно, содержащее фактическое сообщение об ошибке, сгенерированное Lua, которое можно использовать в поисковой системе для поиска подробного описания значения сообщения и распространенных способов устранения, а также трассировки стека, помогающей определить часть кода, которая фактически вызвала ошибку.
Однако некоторые ошибки встречаются чаще других:
my_str = my_str .. "xx"
- Строка с именем «my_str» не должна быть равна нулю при использовании внутри операции конкатенации строк.my_str = my_str + "z"
- Оператор конкатенации — это две точки «..», и попытка использовать знак плюс «+» может пройти во время предварительной компиляции edit-save, но привести к возникновению «Ошибки скрипта» при выполнении этой части скрипта Lua.len = string.long(my_str)
- Оператор длины строки - это решетка '#' (например, #my_str
) или используется функция ' string.len(my_str)
', но попытка использовать неизвестную функцию ' string.long(my_str)
' успешно пройдет предварительную компиляцию edit-save, однако при выполнении этой части скрипта Lua возникнет ошибка «Ошибка скрипта».Существует множество других причин возникновения « ошибки скрипта », но всегда ищите возможность наличия неустановленной, неинициализированной переменной, которая может остановить программу в этой точке.
Чтобы избежать слишком большого количества ошибок одновременно, общая стратегия заключается в том, чтобы вносить "одно небольшое изменение" за раз, выполнять запуск show-preview, а затем сохранять эту проверенную версию после нескольких хороших изменений, чтобы иметь стабильную версию для восстановления, в случае возникновения ужасных ошибок после многочисленных последующих изменений. Примечание: сохранение каждой рабочей копии может быть выполнено в наборе автономных текстовых файлов, возможно, каждый с определенным именем версии (и внутренними комментариями), вместо того, чтобы сохранять каждую версию в ревизиях модуля Википедии.
Чтобы увидеть значение переменной в одной точке модуля:
Функцию error()
можно использовать для отображения значения переменной в любой точке модуля. Таким образом, чтобы узнать значение переменной var
в определенной точке кода, добавьте строку error(var)
в этой точке.
В случае, если переменная является таблицей (назовем переменную tab
), mw.dumpObject(tab)
может использоваться для отображения таблицы. Если переменная не имеет вложенных таблиц, table.concat(tab, ',')
может также использоваться как параметр в error()
функции, т.е. error(table.concat(tab, ','))
.
Для получения переменных и значений, возвращаемых функциями (не локальными в обоих случаях), можно использовать «Debug console». «Debug console» отображается ниже на странице модуля (когда он находится в режиме редактирования). Затем можно использовать mw.log
, mw.logObject
, и =
. Давайте рассмотрим его полезность в следующем примере:
local p = {} p . Hello = 'Hello' function p . calc ( num ) return num end function p . sum_mult ( num ) return num + num , num * num end function p . mtable ( num ) return { num , num + 1 } end return p
Запросы к «Консоли отладки»:
. Консоль отладки не сохраняет запросы, тогда их придется копировать или перезаписывать заново при каждой модификации модуля.
Функции модуля :SimpleDebug можно использовать в случаях, подобных упомянутым выше, или в более сложных случаях:
В некоторых ситуациях модуль Lua может быть более старой попыткой, возможно, измененной различными другими редакторами по ходу дела, с несколькими неизвестными проблемами. Модуль Lua может содержать многочисленные логические ошибки и даже неправильно написанные переменные, если модуль не был должным образом протестирован для всех функций при первоначальной разработке. Сообщение « Ошибка скрипта » появляется только тогда, когда тестовые данные запускают недопустимый раздел кода Lua, поэтому непроверенный модуль может содержать много скрытых ошибок, которые будут обнаружены только тогда, когда более широкие тестовые данные активируют больше областей исходного кода или используют больше внутренних функций.
Распространенная и сложная проблема заключается в попытке расширить старый модуль для новых функций, не зная, что некоторые предыдущие нерешенные ошибки будут срабатывать только при добавлении расширенной функциональности. Обратите внимание, что ошибки часто не в недавно добавленном скрипте Lua, а молчаливо ждут в старых разделах, чтобы сработать (сюрприз), когда новый код активирует другие части скрипта Lua. Скрытая ошибка может быть такой простой, как неопределенное (или неправильно написанное) имя переменной, которое было обработано со значением по умолчанию, но при использовании с недавно добавленными функциями генерирует совершенно загадочные результаты, как будто новый код имел ошибки, когда на самом деле старые неправильно написанные переменные в других областях полностью испортили работу новых функций.
Тактика для работы со старыми ошибками заключается в планировании запуска специальных дополнительных тестовых данных для активации областей кода или показа вывода отладочного отображения, где может быть добавлен новый скрипт Lua, чтобы обеспечить проверку работоспособности затронутых областей, прежде чем добавлять слишком много новой, подробной логики. В большинстве случаев обратите внимание: « вычитка — самая быстрая форма тестирования», если у вас есть терпение или сила умственной памяти, чтобы просмотреть детали старого исходного кода. Однако другая тактика заключается в резервировании определенных значений тестовых данных для запуска кода отладочного отображения, который выводит значения всех связанных данных на экран или предоставляет список дерева вызовов, чтобы гарантировать, что логика перетекает в различные разделы функций, как и ожидалось. Во многих случаях человеческая память не может справиться с деталями, выходящими за пределы 5-9 переменных, и поэтому отладочное отображение становится более простым вариантом, несмотря на дополнительное время, необходимое для записи операторов отладки-печати в модуль Lua. Будьте осторожны и действуйте медленно, поскольку после добавления большого количества новых скриптов Lua может возникнуть проблема с угадайкой: были ли проблемы вызваны «всем новым материалом», а не уже существующими ошибками в старом скрипте Lua.
В английской Википедии установлено расширение Template Sandbox. Существует синергия между расширениями "template sandbox" и "Scribunto", которая позволяет разрабатывать и изменять модули Lua на приватных (т.е. в пользовательском пространстве) страницах, прежде чем выносить их в глобальное пространство.
Давайте рассмотрим практический пример. Для этого примера предположим, что ваше имя пользователя — «Разработчик Lua». Допустим, вы хотите протестировать исправление ошибки или улучшение модуля String . Есть две причины, по которым вы не можете сделать это напрямую: этот модуль содержит функции, которые используются сотнями шаблонов, включенных в миллионы статей. Любая ошибка приведет к огромным сбоям в работе Википедии. Вторая причина более прозаична: поскольку этот модуль настолько центральный, он также защищен, и наш пользователь «Разработчик Lua» не имеет необходимых прав для изменения этого модуля.
Итак, первым шагом в «песочнице» является копирование Module:String на личную страницу User:Lua Developer/sandbox/Module:String. Теперь наш разработчик может редактировать модуль по своему усмотрению. В любой момент она может открыть Special:TemplateSandbox , используя префикс «Sandbox» по умолчанию, который в ее случае будет «User:Lua Developer/sandbox». Это означает, что при просмотре любой страницы со страницы песочницы всякий раз, когда парсер встречает Template T или Module M , он сначала будет проверять, существует ли страница с именем «User:Lua Developer/sandbox/Template:T» или «User:Lua Developer/sandbox/Module:M», и если это так, парсер будет использовать их для проанализированной страницы вместо тех, что находятся в «реальных» пространствах имен Module и Template. Любой шаблон или модуль, которые не существуют под «префиксом Sandbox», будут извлечены парсером из соответствующего пространства имен.
Из песочницы шаблонов разработчик может просматривать любую страницу, а также вводить сырой викитекст и запрашивать у парсера возможность проанализировать его с помощью поддельных шаблонов и модулей, созданных под «префиксом песочницы».
В Wikipedia есть небольшое извращение относительно регистра имен страниц: она преобразует первый символ имени страницы в верхний регистр, независимо от того, как он был введен. Чтобы компенсировать это, она также преобразует первую букву шаблона (при включении) и модуля (при вызове) в верхний регистр. Однако это не распространяется на модули, хранящиеся в пространстве имен User:, просматриваемые через специальную песочницу Template, потому что в песочнице «первая буква» больше не является первой буквой. Вот реальный пример: для реальных модулей, скажем, Module:String , программное обеспечение mediawiki позволит вам использовать для возврата «Here I em» (попробуйте). Оно также позволит вам использовать для получения того же результата:{{#invoke:String|replace|Hara I am|a|e}}
{{#invoke:string|replace|Hara I am|a|e}}
Однако если наш разработчик создаст страницу с именем User:Lua Developer/sandbox/Module:string, он не сможет вызвать этот модуль каким-либо образом, потому что парсер будет искать страницу с именем «Module:String», а не «Module:string» под префиксом sandbox, Wikipedia не преобразует имя в «Module:String» (потому что она преобразует только первый символ в имени страницы) и не найдет ее, поэтому она возьмет модуль из основного пространства имен (если такой модуль существует) или сообщит, что модуль не существует.
Верхний/нижний регистр корректно обрабатывается для всех модулей при обычном использовании, которые размещены в пространстве имен Module:.
Еще один вопрос стратегии: добавление разделов debug-display не замедляет код Lua, как это могло бы замедлить скорость выполнения шаблона на основе разметки, поскольку Lua может обрабатывать сотни условий if с большой скоростью. Даже добавление дополнительного оператора if для каждой переменной Lua не сильно замедляет скорость по сравнению с замедлением шаблона примерно на 50% при добавлении аналогичных выражений if внутри шаблона разметки. Не стесняйтесь добавлять много разделов debug-display в модуль Lua или добавлять несколько тестов проверки параметров в качестве дополнительных операторов if для проверки значений переменных с целью обнаружения типичных неверных данных.
Программное обеспечение Lua изначально было настроено с небольшим, 10-секундным лимитом тайм-аута для комбинированной работы всего кода Lua при форматировании страницы. Для сравнения, шаблоны на основе разметки имеют 60-секундный тайм-аут (в 6 раз большее ограничение по времени), и когда серверы медленные, шаблоны на основе разметки могут форматировать идеально, вплоть до 59 секунд, но части шаблонов Lua будут остановлены на 10-секундном лимите. Сообщение об ошибке может быть следующим:
В отличие от шаблонов на основе разметки, отформатированная страница будет содержать "ошибку скрипта" для каждого последующего вызванного модуля Lua, как текст для сохранения в копии кэша страницы. Опасность ограничения по времени ожидания возникает в редкие периоды задержки сервера в 3-4 раза медленнее, когда 3-секундная операция Lua может замедлиться до 12-секундной продолжительности при загруженных серверах и, таким образом, исказить обработку для сохранения "ошибки скрипта" на отформатированной странице, которую смогут увидеть тысячи читателей.
Общие усилия кажутся нестабильными или ненадежными, как будто Lua внезапно «слишком устает» и начинает жаловаться, сохраняя «Ошибку скрипта» в результирующей странице, где вместо этого ожидался бы форматированный текст. Проблема тайм-аута встречается довольно редко, и когда форматированная статья содержит текст «Ошибка скрипта» внутри страницы, то, возможно, стоит немного отредактировать страницу, чтобы внести небольшое изменение, чтобы принудительно заменить страницу чистым запуском Lua.
Запуск кода через IDE полезен из-за его функций подсветки текста, которые могут помочь вам быстро обнаружить синтаксические ошибки. Любая IDE с возможностью установки плагина подсветки текста Lua должна подойти. Это может быть как простая среда, например Notepad++ (с выбором Lua в меню языка), так и полнофункциональная среда, например Visual Studio Code .
Пошаговая отладка — это мощный инструмент, который позволяет вам проходить по коду по одной строке за раз и наводить курсор на переменные, чтобы увидеть их содержимое во время выполнения. IDE, которые легко поддерживают пошаговую отладку Lua, включают ZeroBrane Studio и IntelliJ IDEA с различными плагинами отладчика (Emmy Lua или Lunalysis).
Lua использует уникальный вариант регулярных выражений , который не поддерживается топовыми инструментами RegEx. Одним из инструментов, который можно использовать для проверки Lua RegEx, является Lua Patterns от GitSparTV.
Если вы все еще не можете решить проблему и не знаете, как действовать дальше, оставьте заметку на Wikipedia:Lua requests с просьбой о помощи в отладке.