В Lua, как вы импортируете модули?

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

require "name"

или

local name = require "name"

Также вы явно объявляете системные модули как локальные переменные? Например.

local io = require "io"

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

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

Ответы

Ответ 1

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

Ответ 2

Некоторые библиотеки работают только одним способом, а некоторые работают иначе.

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

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

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

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


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

Изменить: функции локализации теперь обескуражены. Чтобы найти случайные глобальные переменные, используйте linter, например 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;
}

Ответ 3

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

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

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

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