В Lua как вы импортируете модули? - PullRequest
15 голосов
/ 30 августа 2011

Используете ли вы

require "name"

или

local name = require "name"

Кроме того, вы явно объявляете системные модули как локальные переменные? Э.Г.

local io = require "io"

Пожалуйста, объясните свой выбор.

Программирование в Lua 2ed говорит: «Если она предпочитает использовать более короткое имя для модуля, она может установить для него локальное имя», и ничего о том, что local m = require "mod" быстрее, чем require "mod", ничего не значит. Если нет никакой разницы, я бы предпочел использовать более чистую декларацию require "mod" и не стал бы писать декларации для предварительно загруженных системных модулей.

Ответы [ 3 ]

7 голосов
/ 01 сентября 2011

Некоторые библиотеки работают только в одну сторону, а некоторые работают только в другую сторону

Синтаксис require "name" был введен в lua 5.1; как примечание; этот вызов не всегда возвращает модуль; но ожидалось, что будет создано глобальное имя библиотеки (так что теперь у вас есть _G.name для использования библиотеки). Например, в более ранних версиях gsl, если вы сделали local draw = require"draw", локальный draw будет содержать true; и тень на глобальный draw, созданный библиотекой.

Вышеуказанное поведение поощряется функцией module ==>, которая теперь относительно не рекомендуется, любой хорошо написанный новый код не будет ее использовать.

Синтаксис local name = require"name" стал предпочтительным в последнее время (около 2008 года?); когда было решено, что модули, устанавливающие для вас глобальные переменные, были плохой вещью Как пункт: все мои библиотеки не устанавливают глобальные переменные, а просто возвращают таблицу функций; или в некоторых других случаях они возвращают функцию, которая работает как инициализатор для корневого объекта.

tldr; В новом коде вы должны использовать последний синтаксис local name = require"name"; он работает в подавляющем большинстве случаев, но если вы работаете с некоторыми старыми модулями, они могут не поддерживать его, и вам придется просто использовать require"module".


Чтобы ответить на ваш добавленный вопрос : вам требуются системные модули ?: нет; вы просто предполагаете, что они уже необходимы; но я локализую все используемые мной функции (обычно сгруппированные по строкам по модулю, из которого они поступили), в том числе из внешних библиотек. Это позволяет легко увидеть, на какие функции действительно опирается ваш код; а также удаление всех GETGLOBAL из вашего байт-кода.

Редактировать: локализация функций теперь не рекомендуется. Чтобы найти случайные глобалы, используйте линтер типа luacheck

Пример модуля в (моем) предпочтительном стиле ; будет работать только с синтаксисом local name = require"name".

local my_lib = require"my_lib"

local function foo()
    print("foo")
end

local function bar()
    print("bar", my_lib.new())
end

return {
    foo = foo;
    bar = bar;
}
6 голосов
/ 31 августа 2011

Любой из них работает.Хранение в локальном хранилище не изменит того факта, что модуль может иметь зарегистрированные глобальные функции.

1 голос
/ 31 августа 2011

Я бы сказал, что это в основном сводится к тому, что вы предпочитаете, но есть некоторые исключения в зависимости от того, что вы пишете. Создание локальной ссылки даст вам некоторую скорость, но в большинстве случаев это не имеет смысла оптимизировать. Вы также должны указать свой локальный адрес для используемой вами функции, а не для таблицы модулей.

Если вы пишете в библиотеке, я бы порекомендовал создать локальные ссылки для всех глобальных переменных, которые вы используете. Даже если вы не используете функцию module(), которая изменяет глобальную область видимости для следующего кода. Причина этого в том, что она не позволяет вашей библиотеке вызывать глобальные переменные, которые были изменены после загрузки библиотеки.

Выполнение local io = require’io’ гарантирует, что вы получите таблицу от package.loaded.io, даже если _G.io был заменен другой таблицей. Я обычно не делаю это сам. Я ожидаю, что io уже будет загружен и не изменен, когда я пишу Lua.

Вы также должны помнить, что существует несколько способов написания модуля Lua. Некоторые модули не возвращают свою таблицу модулей, в то время как другие не создают глобальную переменную. Наиболее распространенным решением является создание и возврат глобальной переменной, но на это не всегда можно положиться.

...