Проект:Технические работы/Модули/ЧаВо

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Что такое Lua и Scribunto?
Lua — это интерпретируемый язык программирования, представляет собой свободное программное обеспечение с открытыми исходными текстами на языке Си.
Scribunto — это расширение движка MediaWiki (на котором работает Википедия), позволяющее применять для генерации текста страниц скрипты, написанные пользователями на Lua.
Зачем это надо?
В Википедии и других википроектах возникает надобность в автоматизации и облегчении оформления страниц, создаваемых участниками. В движке есть много различных средств для этого (такие, как шаблоны, категории, таблицы и др.), и разработчики регулярно добавляют новые. Но было замечено, что имеющимся средствам не хватает гибкости, а ресурсы штатных программистов нашего некоммерческого проекта ограничены и не могут поспеть за всеми запросами многочисленных рядовых участников. Внедрение расширения Scribunto позволяет всем участникам сообщества Википедии быстро внедрять собственные небольшие программы на несложном, но мощном языке Lua, которые дополняют парсер нужными конструкциями.
Как применить решение на Lua на странице Википедии?
Используйте специальную функцию парсера {{#invoke:Модуль|fn|Аргумент1|Аргумент2|имяАргумента=Значение Аргумента}}. На место этой конструкции будет подставлен в виде строки результат выполнения функции fn(frame), где frame — объект фрейма, содержащий информацию о переданных параметрах (frame.args={"Аргумент1", "Аргумент2", ["имяАргумента"] = "Значение Аргумента"}). В этой строке работает HTML и [[вики-разметка]], но конструкции в {{фигурных скобках}} являются обычным текстом.
Что такое модули Lua?
Модули представляют собой страницы Викпедии в специальном пространстве имён «Модуль» (алиас «Module»). На этих страницах не работают тэги HTML, шаблоны и категории, а текст открывается в специальном редакторе Lua. Каждый модуль представляет собой программу, которая выполняется интерпретатором Lua в среде Scribunto и в конце работы возвращает с помощью оператора return некоторое значение (или выдаёт сообщение об ошибке). Значение большинства модулей — это таблица, в которой функции сопоставлены своим именам; модули могут возвращать что угодно ещё, но только такие таблицы могут использоваться в конструкции {{#invoke:}}.
Любой пользователь может создавать и редактировать модули, хотя некоторые модули могут быть защищены от неадминистраторов.
Можно ли добавить на страницу модуля категории и документацию?
Не только можно, но и нужно! Просто разместите всё необходимое на подстранице документации «Модуль:имя модуля/doc», не забыв обернуть категории для модуля в тэги <includeonly></includeonly>, и оно появится в шапке страницы модуля. Опишите, как работают все функции, экспортируемые модулем. Не стоит забывать и о комментариях к сложным местам кода (их можно вводить после символов -- до конца строки кода, можно делать и многострочные с помощью --[[...]]).
Как передать параметры вызова в функцию?
Функция, вызываемая из модуля через {{#invoke:Модуль|fn|...}}, получает единственный параметр — объект фрейма. Тот же самый объект можно достать в любом месте кода функцией mw.getCurrentFrame(). Аргументы доступны в виде frame.args[1], frame.args[2] и т. п.; аргументы с номером (1, 2, 3…) доступны по ключу-числу, даже если он был передан в явном виде; аргументы с другими именами доступны по ключу-строке (например, frame.args['именованный параметр']). В параметрах с ключами, переданными в явном виде с помощью знака =, подрезаются крайние пробелы, как и у обычных шаблонов. Иногда можно и не передавать параметры в вызов {{#invoke:Модуль|fn}}, см. ниже.
Стоит ли использовать модуль Lua напрямую в статье Википедии?
Нет, чтобы не смущать малоопытных в этой сфере редакторов, лучше включать вызовы {{#invoke:}} в шаблоны. Через объект frame:getParent() модулю Lua доступны параметры шаблона, из которого он вызван, и свойства вызвавшей страницы.
Какова потребность Lua в ресурсах? Не лучше ли обойтись функциями парсера?
Lua потребляет не слишком много ресурсов и работает довольно быстро, но определённые ограничения есть. Если задача легко решается функциями парсера без применения Lua, конечно, не стоит писать для неё модуль, но для задач, для которых подходящих стандартных функций не предусмотрено (необходимость использования циклов, сложного анализа частей строк и т. п.) Lua предпочтительней. Но прежде всего стоит подумать и обсудить с сообществом, есть ли вообще такая проблема.
Что будет, если в программе возникнет ошибка?
Ничего страшного, бывает. Вместо результата функции будет показан текст Ошибка скрипта, при щелчке по которому выпадет окошко с сообщением интерпретатора, что и где пошло не так. При щелчке по ссылкам в этом сообщении открывается окно редактирования модуля, в котором курсор сразу попадает на нужную строку. Хотя лучше, конечно, чтобы всё работало хорошо, см. ниже.
Как отладить скрипт Lua, не сохраняя его много раз?
Под окошком редактирования модуля есть два полезных поля. В одно из них вы можете ввести название существующей страницы и посмотреть, как изменённая версия модуля будет на ней работать. Второе — это окно отладчика. Там можно вводить любую строчку текста на Lua; отладка функции fn, которую планируется применять в вызове {{#invoke:Модуль|fn|а1|a2|ип=иa|a3}}, обычно выглядит так:
=p.fn{args={"a1","a2",["ип"]="иa","a3"}} --простейший случай
=p.fn(mw.getCurrentFrame():newChild{title="обычно не важно",args={"a1","a2",["ип"]="иa","a3"}}) --если функция подразумевает использование методов объекта фрейма
=p.fn(mw.getCurrentFrame():newChild{title="Шаблон:Ша",args={"aш1","aш2",["ипш"]="иaш"}}:newChild{title="Модуль:Текущий модуль",args={"a1","a2",["ип"]="иa","a3"}})
 --если функцию тестируем на применение через шаблон {{Ша|аш1|аш2|ипш=иаш}}, наиболее точный способ
Отладочный вывод из программы на эту консоль можно также делать, не ставя в начале =, с помощью функций mw.log() (синоним print()) и mw.logObject().
Можно ли нарисовать на Lua картинку?
Нет, нельзя, Scribunto генерирует только текст. Но можно передать соответствующий вывод Scribunto в тэг <graph />.
Можно ли с помощью Lua добавить на страницу интерактивность?
Нет, Lua не предназначена для реакций на действия читателя статьи, она только генерирует её вики-текст при изменениях. Интерактивность (когда она нужна в энциклопедии) достигается другими средствами, см. например ВП:ПСК.
Используются ли глобальные переменные после одного вызова {{#invoke:}} в последующих?
Нет, все вызовы полностью независимы, каждый из них интерпретирует модуль (даже один и тот же) заново «с чистого листа».
Хорошо ли Lua понимает русские и все прочие буквы?
Оригинальный движок Lua считает, что символ=байт, поэтому русские буквы и другие многобайтные символы Юникода могут обрабатываться не совсем так, как вы, быть может, ожидали. С другой стороны, строки в Юникоде вполне корректно передаются в/из Lua и хранятся в переменных. Для строк, где могут быть многобайтные символы, применяйте функции библиотеки mw.ustring, в том числе вместо #s пишите mw.ustring.len(s) (впрочем, эти функции медленнее обычных).
В моём модуле применяется большая таблица данных, можно ли не рассчитывать её при каждом из многих вызовов его функций на странице?
Да, статическая информация (не содержащая функций и т. п. и не доступная для изменения функциям в процессе их работы) может быть сгенерирована отдельным специальным модулем. Напишите его и получайте его результат из используемых на странице модулей функцией mw.loadData(). Он будет выполнен только один раз при генерации страницы.