--- title: Пишем на Lua layout: default root: ../.. idx: 1.2 description: Введение в Lua redirect_from: /ru/chapters/lua.html --- ## Введение В этой главе вы узнаете, как писать на Lua и какие для этого нужны инструменты. Также вы познакомитесь с некоторыми полезными техниками. - [Программирование](#programming) - [Пишем на Lua](#coding-in-lua) - [Редактор](#code-editors) - [Области видимости](#local-and-global-scope) - [Используйте локальные переменные везде](#locals-should-be-used-as-much-as-possible) - [Подключение других скриптов](#including-other-lua-scripts) ## Программирование Программирование — это когда вы берёте задачу (например, сортировка списка) и превращаете её в простые шаги, который компьютер сможет выполнить. Обучение вас программированию не является целью этой книги. Тем не менее, эти сайты могут оказаться для вас полезными: * [Codecademy](http://www.codecademy.com/) один из лучших ресурсов для обучения программированию. Здесь есть интерактивные обучающие примеры. * [Scratch](https://scratch.mit.edu) — хороший ресурс для того, чтобы начать с самых основ и научиться технике решения задач в программировании. Он отлично подойдёт детям и подросткам. * [Programming with Mosh](https://www.youtube.com/user/programmingwithmosh) — прекрасный YouTube-канал по обучению программированию. ### Пишем на Lua Обучение вас программированию на Lua также не является целью этой книги. Рекомендую книгу [Programming in Lua (PiL)](https://www.lua.org/pil/contents.html) — она прекрасно подойдёт для входа в Lua. ## Редактор Текстовый редактор с подсветкой синтаксиса очень полезен при написании на Lua. Слова и символы выделяются разными цветами в зависимости от их назначения. Это облегчает поиск ошибок и несоответствий. Например: ```lua function ctf.post(team,msg) if not ctf.team(team) then return false end if not ctf.team(team).log then ctf.team(team).log = {} end table.insert(ctf.team(team).log,1,msg) ctf.save() return true end ``` В этом примере подсвечены ключевые слова, такие как: `if`, `then`, `end` и `return`. Стандартные фукнции Lua, такие как `table.insert`, также будут подсвечены. Широко используемые редакторы для Lua: * [VSCode](https://code.visualstudio.com/): открытй (как Code-OSS или VSCodium), популярный и к нему есть [плагин для Minetest](https://marketplace.visualstudio.com/items?itemName=GreenXenith.minetest-tools). * [Notepad++](http://notepad-plus-plus.org/): простой, только для Windows. Есть и множество других подходящих редакторов. ## Области видимости Переменные могут быть локальными и глобальными. К глобальным переменным можно обращаться из любого места в скрипте и даже из другого мода. ```lua function one() foo = "bar" end function two() print(dump(foo)) -- Выведет сообщение: "bar" end one() two() ``` Локальные же переменные доступны только там, где они объявлены. По умолчанию, все переменные в Lua глобальные, и вам необходимо явно помечать локальные переменные словом `local`. ```lua -- Доступна в любом месте этого файла local one = 1 function myfunc() -- Доступна только внутри этой функции local two = one + one if two == one then -- Доступна только внутри условного оператора local three = one + two end end ``` ### Используйте локальные переменные везде Старайтесь использовать локальные переменные везде, где только можно. Мод должен создавать только одну глобальную переменную с таким же именем, как и у мода. Создание любых других глобальных переменных считается плохим тоном, и Minetest будет предупреждать об этом сообщением: Assignment to undeclared global 'foo' inside function at init.lua:2 Чтобы исправить это, используйте ключевое слово "local": ```lua function one() local foo = "bar" end function two() print(dump(foo)) -- Выведет сообщение: nil end one() two() ``` Запомните, что "nil" означает **не инициализировано**: переменной ещё не было присвоено значение, перменная не существует или была удалена (было присвоено значение nil). Функции — это особый тип переменных, но они также должны быть объявлены локально, ведь в других модах могут оказаться свои функции с такими же именами. ```lua local function foo(bar) return bar * 2 end ``` Чтобы позволить другим модам вызывать ваши функции, необходимо создать таблицу с таким же именем, как у вашего мода, и добавить в неё нужные функции. Такая таблица обычно называется "API мода" или namespace. ```lua mymod = {} function mymod.foo(bar) return "foo" .. bar end -- В другом моде или скрипте: mymod.foo("foobar") ``` `function mymod.foo()` то же самое что и `mymod.foo = function()`, только выглядит лучше. ## Подключение других скриптов Лучше всего подключать другие Lua-скрипты в мод с помощью функции *dofile*. ```lua dofile(core.get_modpath("modname") .. "/script.lua") ``` Скрипт может веруть значение, через которое предоставит доступ к локальным переменным: ```lua -- script.lua local module = {} module.message = "Hello World!" return module -- init.lua local ret = dofile(core.get_modpath("modname") .. "/script.lua") print(ret.message) -- Hello world! ``` В [следующей главе](../quality/clean_arch.html) вы узнаете, как лучше всего разбивать код мода.