package.path и package.cpath
Настраивайте пути поиска для модулей Lua и C.
«package.path и package.cpath» — бесплатный урок Lua Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Содержимое package.path
package.path — это строка с шаблонами поиска, разделёнными точками с запятой. Каждый шаблон содержит заполнитель ?, который заменяется именем модуля (точки преобразуются в разделители каталогов). Lua проверяет шаблоны по порядку, пока не найдёт файл.
print(package.path)
-- ./?.lua;./?.luac;/usr/local/share/lua/5.4/?.lua;...
-- Dots in module names become directory separators
-- require("foo.bar") -> searches for foo/bar.lua
print(("foo.bar"):gsub("%.", "/")) -- foo/barДобавление путей поиска
Добавляйте пути в начало package.path, чтобы указать каталоги с высоким приоритетом при поиске. Добавление в конец задаёт расположения с более низким приоритетом. Установите эти пути до вызовов require, которым они необходимы.
-- Add multiple directories
package.path = table.concat({
"./?.lua",
"./lib/?.lua",
"./lib/?/init.lua",
package.path, -- keep existing paths
}, ";")
-- Now require("json") searches:
-- ./json.lua -> ./lib/json.lua -> ./lib/json/init.lua -> ...package.cpath для расширений C
package.cpath — это путь поиска модулей-расширений C (динамических библиотек: .so в Linux, .dll в Windows, .dylib в macOS). Соглашение об именовании соответствует соглашениям операционной системы для динамических библиотек.
print(package.cpath)
-- ./?.so;/usr/local/lib/lua/5.4/?.so;...
-- Add a local C library directory
package.cpath = "./clib/?.so;" .. package.cpath
-- require("myextension") will now search:
-- ./clib/myextension.soПеременная окружения LUA_PATH
Переменная окружения LUA_PATH задаёт начальное значение package.path. Последовательность ;; в LUA_PATH заменяется путём по умолчанию. Используйте это для настройки путей поиска без изменения скриптов — это удобно при развёртывании.
-- Set before launching Lua:
-- export LUA_PATH="./?.lua;./lib/?.lua;;"
-- The ";;" expands to the built-in default path
-- In Lua, check what was set:
print(package.path)
-- You can also use LUA_CPATH for C paths:
-- export LUA_CPATH="./clib/?.so;;"package.searchpath
package.searchpath(name, path) ищет файл, соответствующий имени, в строке пути. Функция возвращает первое найденное совпадение либо nil и сообщение об ошибке со списком всех проверенных расположений. Это удобно для поиска файлов без их фактической загрузки.
local file, err = package.searchpath("json", package.path)
if file then
print("Found:", file)
else
print("Not found. Tried:\n" .. err)
end
-- Useful for checking if a module exists:
local function moduleExists(name)
return package.searchpath(name, package.path) ~= nil
end
print(moduleExists("json"))Алгоритм поиска require
При вызове require("mod") Lua выполняет следующие шаги: (1) проверяет package.loaded, (2) проверяет package.preload, (3) ищет файл .lua в package.path, (4) ищет библиотеку C в package.cpath. Побеждает первое найденное совпадение.
-- Simulate what require does:
local function myRequire(name)
-- 1. Check cache
if package.loaded[name] ~= nil then
return package.loaded[name]
end
-- 2. Check preload
if package.preload[name] then
return package.preload[name]()
end
-- 3. Search path
local file = package.searchpath(name, package.path)
if file then
return dofile(file) -- simplified
end
error("module not found: " .. name)
endФункции загрузки
package.searchers (ранее package.loaders) — это массив функций, которые пытаются найти и загрузить модуль. В эту таблицу можно добавлять собственные функции поиска. Каждая такая функция получает имя модуля и возвращает функцию загрузки или nil.
-- Add a custom searcher that loads from a table
local builtins = {
myconfig = function()
return {host="localhost", port=8080}
end
}
table.insert(package.searchers, 1, function(name)
local loader = builtins[name]
if loader then return loader end
end)
local cfg = require("myconfig")
print(cfg.host, cfg.port) -- localhost 8080Соглашения об именах модулей
Имена модулей имеют иерархическую структуру и используют точки: "mylib.utils". Обычно пространством имён верхнего уровня служит имя проекта или организации, чтобы избежать конфликтов. Стандартом является нижний регистр. Не используйте дефисы в именах модулей (вместо них используйте символы подчёркивания), поскольку дефисы конфликтуют с синтаксисом Lua.
-- Good: hierarchical, lowercase
-- require("myapp.db.connection")
-- require("myapp.utils.string")
-- Bad: dashes cause syntax issues in dot notation
-- local my-module = require("my-module") -- SYNTAX ERROR
local mymodule = require("my_module") -- okОтладка путей
Если require не может найти модуль, сообщение об ошибке содержит все проверенные пути. Выведите package.path, чтобы увидеть порядок поиска. Используйте package.searchpath, чтобы интерактивно проверить пути конкретного модуля.
-- Debug require failures:
local ok, err = pcall(require, "missing_module")
if not ok then
-- The error message shows all tried paths
print("require failed:")
print(err)
print("\nCurrent package.path:")
for path in package.path:gmatch("[^;]+") do
print(" " .. path)
end
endСброс пути на значение по умолчанию
Если нужен чистый минимальный путь без системных значений по умолчанию, можно полностью сбросить package.path. Это полезно во встроенных средах Lua, где файловая система ограничена или изолирована.
-- Minimal path for embedded environment
package.path = "./?.lua;./lib/?.lua"
package.cpath = "./?.so"
-- Or get just the current directory patterns:
local function justLocal()
return "./?.lua;./?/init.lua"
end
print("Minimal path:", justLocal())Быстрая проверка
Что обозначает ? в шаблоне package.path?
Повторение: package.path
Краткое содержание:
package.path: шаблоны поиска файлов Lua;?= имя модуляpackage.cpath: шаблоны поиска библиотек C- Добавляйте пути в начало, чтобы задать каталогам высокий приоритет
- Переменные окружения
LUA_PATH/LUA_CPATHзадают начальные пути package.searchpath: проверка доступности модуля для поиска- Добавляйте собственные функции поиска через
package.searchers
Часто задаваемые вопросы
Урок «package.path и package.cpath» бесплатный?
Да — полный текст урока «package.path и package.cpath» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «package.path и package.cpath»?
Настраивайте пути поиска для модулей Lua и C. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «package.path и package.cpath»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Функция require
- Создание файла модуля
- package.path и package.cpath
- Шаблоны модулей и рекомендации