Справочное руководство по языку Lua 5.1 :: 5.3 - Обработка таблиц



5.3 - Модули

Библиотека пакетов предоставляет основные возможности для загрузки и построения модулей в Lua. Также она (библиотека, примечание переводчика) экспортирует две функции в глобальное окружение:require и module.Остальные экспортируются в таблицу package.


module (name [, ···])

Создает модуль. Если package.loaded[name] содержит таблицу, то эта таблица является модулем. В противном случае, если существует глобальная таблица t с данным именем name, то эта таблица – модуль.. Иначе, если таблица не найдена, то создается новая таблица t и эта таблица помещается в поле - package.loaded[name] Эта функция также инициализирует t._NAME заданным именем name, t._M собственно модулем (самой t), а t._PACKAGE именем пакета (полное имя модуля без последнего компонента; см. ниже). В конце module устанавливает t как новое окружение текущей функции и новое значение из package.loaded[name], т.о.require возвращает t.

Если name – составное (compound) имя (т.е., компоненты имени разделены точками), module создает (или повторно использует, если уже существует) таблицы для каждого компонента. Например, если name равно a.b.c, то module сохраняет модуль в поле c поля b глобального объекта a.

Данная функция может получать дополнительные опции options после имени модуля, где каждая опция является функцией, которая будет применена к модулю.


require (modname)

Загружает данный модуль. Функция начинается с проверки таблицы package.loaded для определения загружен модуль modname или нет. Если загружен, то require возвращает значение, хранящееся в package.loaded[modname]. В противном случае, она пытается найти загрузчик (loader) для данного модуля.

При поиске загрузчика, require сначала запрашивает package.preload[modname]. Если там есть значение, это значение (оно должно быть функцией) является загрузчиком. В противном случае require ищет Lua загрузчик, используя путь (path), хранящийся в package.path.. Если результат не достигнут, производит поиск C загрузчика, используя путь, хранящийся в package.cpath. Если поиск также безуспешен, используется универсальный загрузчик всё-в-одном (all-in-one) (см. ниже).

При загрузке C библиотеки, require сначала использует возможность динамического связывания (dynamic link facility) для связывания (link) приложения с библиотекой. Затем она пытается найти C функцию внутри этой библиотеки с определенным именем и использовать её как загрузчик. Имя этой C функции составляется из строки "luaopen_" и к ней добавляется имя модуля, в котором точки заменены символом подчеркивания. Кроме того, если имя модуля содержит дефис, то начало имени до первого дефиса (включая его) удаляется. Например, если имя модуля a.v1-b.c, имя функции будет luaopen_b_c.

Если require не находит ни Lua библиотеки, ни C библиотеки для модуля, она вызывает универсальный загрузчик, называемый всё-в-одном (all-in-one loader). Этот загрузчик ищет C путь для библиотеки по основному имени (root name) данного модуля. Например, при запросе a.b.c, будет произведен поиск C библиотеки для a. Если она найдена, производится поиск открывающей функции; в нашем примере, это будет luaopen_a_b_c. Это позволяет одному пакету содержать несколько C подмодулей (submodules) в одной библиотеке, поскольку каждый подмодуль имеет свою функцию открытия.

Как только загрузчик найден, require вызывает его с одним параметром: modname. Если загрузчик возвращает какое либо значение, require помещает его в package.loaded[modname]. Если загрузчик ничего не возвращает, то package.loaded[modname] устанавливается функцией require в true. В любом случае, require возвращает значение из package.loaded[modname].

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


package.cpath

Путь, используемый в require для поиска C  загрузчика.

Lua инициализирует C  путь package.cpath аналогично инициализации Lua пути package.path, используя переменную окружения LUA_CPATH (плюс путь по умолчанию, определенный в luaconf.h).


package.loaded

Данная таблица используется функцией require для проверки, загружен модуль или нет. Если Вам нужен модуль modname и package.loaded[modname] не равно false, require просто возвращает значение, хранящееся там.


package.loadlib (libname, funcname)

Динамическое связывание хостовой программы с C библиотекой libname. Внутри этой библиотеки производится поиск функции с именем funcname и она возвращается как C функция. (Поэтому, funcname должно соответствовать протоколу (см. lua_CFunction)).

Это функция низкого уровня (low-level function). Она игнорируется пакетной и модульной системой.В отличии от require, здесь не производится поиск путей и не производится автоматическое добавление расширений (extensions). libname должно быть полным именем файла C библиотеки, включая, если необходимо, путь и расширение. funcname должно быть именем, которое экспортировано из C библиотеки (это имя зависит от C компилятора и компоновщика (linker)).

Эта функция не поддерживается ANSI C. Поэтому это доступно не на всех платформах (доступно на Windows, Linux, Mac OS X, Solaris, BSD, плюс другие Unix системы, которые поддерживают dlfcn стандарт).


package.path

Путь, используемый функциейrequire< для поиска Lua загрузчика.

При старте, Lua инициализирует эту переменную значением переменной окружения LUA_PATH или значением по умолчанию из luaconf.h, если переменная окружения не определена. Любое вхождение строки ";;" в переменную среды окружения замещается значением по умолчанию.

Путь – это последовательность шаблоном (templates), разделенных точкой с запятой. Для каждого шаблона, require будет заменять каждый вопросительный знак на имя файла filename, which is modname with each dot replaced by a "directory separator" (such as "/" in Unix); then it will try to load the resulting file name. Поэтому, например, если Lua путь содержит


            " ./ '.lua;./ '.lc;/usr/local/ '/init.lua "
           

То при поиске загрузки модуля foo будет выполняться поиск файлов ./foo.lua, ./foo.lc и /usr/local/foo/init.lua, именно в этом порядке.


package.preload

Таблица, хранящая загрузчики для модулей (см. require).


package.seeall (module)

Устанавливает метатаблицу для модуля module с полем __index , ссылающимся на глобальное окружение, т.е. этот модуль наследует глобальное окружение.Это будет использоватся как опция для функции module./p>