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