0Pricing
Lua Academy · Урок

Функция require

Загружайте внешние модули с помощью require и изучайте кэширование модулей.

«Функция require» — бесплатный урок Lua Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.

Как работает require

require(modname) загружает и возвращает модуль. Он ищет файл .lua в package.path, а библиотеку C — в package.cpath. Результат кэшируется в package.loaded[modname]: последующие вызовы возвращают кэшированное значение, не выполняя файл повторно.

-- First require: loads and executes math_utils.lua
local math_utils = require("math_utils")

-- Second require: returns cached value (file not re-run)
local math_utils2 = require("math_utils")

print(math_utils == math_utils2)   -- true (same object)
print(package.loaded["math_utils"] == math_utils)  -- true

Возвращаемое значение модуля

Файл модуля должен возвращать значение — обычно таблицу функций. Именно это возвращаемое значение require передаёт вызывающему коду. Если файл ничего не возвращает (или возвращает true), require возвращает это же значение.

-- mymodule.lua:
-- local M = {}
-- function M.hello() print("Hello from module!") end
-- return M

-- In main script:
local m = require("mymodule")
m.hello()   -- Hello from module!

-- The module table is the interface

Кэширование в package.loaded

package.loaded — это таблица, сопоставляющая имена модулей с загруженными значениями. Вы можете вручную задать элемент, чтобы предварительно загрузить имитацию, или присвоить ему nil, чтобы принудительно выполнить повторную загрузку (при следующем вызове require файл модуля выполнится заново).

-- Force reload by clearing cache
package.loaded["mymodule"] = nil
local fresh = require("mymodule")  -- re-executes the file

-- Preload a mock for testing
package.loaded["db"] = {
  query = function() return {} end,
  close = function() end,
}
local db = require("db")  -- gets the mock

Формат package.path

package.path — это список шаблонов, разделённых точками с запятой. Заполнитель ? заменяется именем модуля (точки заменяются разделителями пути). Чтобы добавить каталоги для поиска, можно дописать их в начало package.path.

print(package.path)
-- typically: ./?.lua;./?.luac;/usr/share/lua/5.4/?.lua;...

-- Add local lib directory
package.path = "./lib/?.lua;" .. package.path

-- Now require("utils") will look in ./lib/utils.lua

require, dofile и loadfile

require: кэширует и ищет в package.path. dofile(path): немедленно выполняет файл, не кэширует его и принимает прямой путь. loadfile(path): компилирует, но не выполняет файл, а возвращает функцию. Используйте require для модулей, а dofile — для разовых сценариев.

-- dofile: no caching, direct path
dofile("./scripts/setup.lua")

-- loadfile: compile only, returns function
local fn, err = loadfile("./config.lua")
if fn then
  local result = fn()   -- execute when ready
end

-- require: best for modules
local json = require("json")

require с точками для каталогов

Используйте точки в именах модулей, чтобы обращаться к файлам во вложенных каталогах. require("utils.string") сопоставляется с utils/string.lua (при наличии ? в шаблоне пути). Так организуют библиотеки, состоящие из нескольких файлов.

-- Directory structure:
-- lib/
--   utils/
--     string.lua
--     table.lua
--   init.lua

package.path = "./lib/?.lua;" .. package.path

local strUtils = require("utils.string")   -- loads lib/utils/string.lua
local tblUtils = require("utils.table")    -- loads lib/utils/table.lua

Побочные эффекты инициализации модуля

Файлы модулей выполняются один раз при первом вызове require. Любой код верхнего уровня (вне функций) запускается во время require. Это удобно для одноразовой инициализации, но будьте осторожны: побочные эффекты, такие как сетевые подключения или операции с файлами, выполняются во время импорта.

-- counter.lua:
-- local count = 0   -- initialized once on first require
-- local M = {}
-- function M.increment() count = count + 1 end
-- function M.get() return count end
-- return M

local c = require("counter")
c.increment()
c.increment()
print(c.get())   -- 2

local c2 = require("counter")
print(c2.get())  -- 2 (same instance, cached)

Обработка ошибок в require

Если в файле модуля есть синтаксическая ошибка или при загрузке возникает ошибка, require возбуждает ошибку. Сообщение об ошибке содержит имя модуля и ошибку из самого файла. Используйте pcall, чтобы корректно обрабатывать сбои загрузки модуля.

local ok, mod = pcall(require, "possibly_missing")
if not ok then
  print("Module not available:", mod)
  -- fall back to alternative or default implementation
  mod = {feature = function() return "fallback" end}
end

print(mod.feature())

package.preload

package.preload — это таблица, в которой можно регистрировать функции загрузки по имени модуля. При вызове require("name") Lua сначала проверяет таблицу предварительной загрузки. Это позволяет регистрировать модули без файлов — полезно для встроенного Lua или тестирования.

package.preload["mymath"] = function()
  return {
    double = function(n) return n * 2 end,
    triple = function(n) return n * 3 end,
  }
end

local m = require("mymath")
print(m.double(5))   -- 10
print(m.triple(5))   -- 15

Циклическая загрузка

Циклические зависимости (A требует B, B требует A) обрабатываются частично: перед выполнением модуля Lua сохраняет заполненное значением true место в package.loaded. Если B попытается использовать ещё не завершённую таблицу A, результат может оказаться неполным. Избегайте циклических зависимостей при проектировании модулей.

-- a.lua: local b = require("b"); local M = {}; M.name = "A"; return M
-- b.lua: local a = require("a"); print("a.name:", a.name); return {}

-- When a.lua is loaded:
-- 1. a starts executing
-- 2. requires b -> b starts executing
-- 3. b requires a -> gets partial a (still loading!)
-- 4. a.name may be nil at step 3

print("Avoid circular requires in module design")

Быстрая проверка

Что происходит при повторном вызове require("mod")?

Повторение: require

Краткое содержание:

  • require(name) загружает модуль один раз и сохраняет его в кэше package.loaded
  • Файл модуля возвращает его открытый интерфейс (обычно таблицу)
  • Очистите package.loaded[name], чтобы принудительно загрузить модуль заново
  • Добавьте пути в package.path, чтобы указать дополнительные каталоги для поиска
  • Используйте package.preload для модулей, хранящихся в памяти
  • Избегайте циклических зависимостей

Часто задаваемые вопросы

Урок «Функция require» бесплатный?

Да — полный текст урока «Функция require» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.

Чему я научусь в уроке «Функция require»?

Загружайте внешние модули с помощью require и изучайте кэширование модулей. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Lua Academy?

Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Функция require»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Lua Academy?

Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Функция require
  2. Создание файла модуля
  3. package.path и package.cpath
  4. Шаблоны модулей и рекомендации
← Назад к Lua Academy