minetest_modding_book/_ru/basics/lua.md

7.7 KiB
Raw Blame History

title layout root idx description redirect_from
Пишем на Lua default ../.. 1.2 Введение в Lua /ru/chapters/lua.html

Введение

В этой главе вы узнаете, как писать на Lua и какие для этого нужны инструменты. Также вы познакомитесь с некоторыми полезными техниками.

Программирование

Программирование — это когда вы берёте задачу (например, сортировка списка) и превращаете её в простые шаги, который компьютер сможет выполнить. Обучение вас программированию не является целью этой книги. Тем не менее, эти сайты могут оказаться для вас полезными:

  • Codecademy один из лучших ресурсов для обучения программированию. Здесь есть интерактивные обучающие примеры.
  • Scratch — хороший ресурс для того, чтобы начать с самых основ и научиться технике решения задач в программировании. Он отлично подойдёт детям и подросткам.
  • Programming with Mosh — прекрасный YouTube-канал по обучению программированию.

Пишем на Lua

Обучение вас программированию на Lua также не является целью этой книги. Рекомендую книгу Programming in Lua (PiL) — она прекрасно подойдёт для входа в 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:

Есть и множество других подходящих редакторов.

Области видимости

Переменные могут быть локальными и глобальными. К глобальным переменным можно обращаться из любого места в скрипте и даже из другого мода.

function one()
    foo = "bar"
end

function two()
    print(dump(foo))  -- Выведет сообщение: "bar"
end

one()
two()

Локальные же переменные доступны только там, где они объявлены. По умолчанию, все переменные в Lua глобальные, и вам необходимо явно помечать локальные переменные словом local.

-- Доступна в любом месте этого файла
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":

function one()
    local foo = "bar"
end

function two()
    print(dump(foo))  -- Выведет сообщение: nil
end

one()
two()

Запомните, что "nil" означает не инициализировано: переменной ещё не было присвоено значение, перменная не существует или была удалена (было присвоено значение nil).

Функции — это особый тип переменных, но они также должны быть объявлены локально, ведь в других модах могут оказаться свои функции с такими же именами.

local function foo(bar)
    return bar * 2
end

Чтобы позволить другим модам вызывать ваши функции, необходимо создать таблицу с таким же именем, как у вашего мода, и добавить в неё нужные функции. Такая таблица обычно называется "API мода" или namespace.

mymod = {}

function mymod.foo(bar)
    return "foo" .. bar
end

-- В другом моде или скрипте:
mymod.foo("foobar")

function mymod.foo() то же самое что и mymod.foo = function(), только выглядит лучше.

Подключение других скриптов

Лучше всего подключать другие Lua-скрипты в мод с помощью функции dofile.

dofile(core.get_modpath("modname") .. "/script.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!

В следующей главе вы узнаете, как лучше всего разбивать код мода.