Lua требует дважды mpack в разных файлах не работает - PullRequest
2 голосов
/ 28 мая 2020

Учитывая следующий (полностью полный) Lua файл:

-- test/file1_spec.lua
local mpack = require('mpack')
print(mpack)

Он будет работать без проблем, если я выполню файл с busted : busted test.

И если я обновлю файл для загрузки mpack дважды:

-- test/file1_spec.lua
local mpack = require('mpack')
print(mpack)
local mpack2 = require('mpack')
print(mpack2)

Он по-прежнему работает. Но если я добавлю второй файл (в дополнение к указанному выше) с:

-- test/file2_spec.lua
local mpack = require('mpack')
print(mpack)

, тогда загрузка mpack этого второго файла завершится ошибкой со следующей ошибкой:

test/file2_spec.lua:1: attempt to index a mpack.NIL value

Как требуется работа? Как мне потребовать mpack в разных файлах Lua?

1 Ответ

1 голос
/ 29 мая 2020

Что-то не так с самим модулем mpack, по какой-то причине он не может быть загружен дважды:

-- demo.lua
require('mpack')
-- remove the loaded package from a cache, otherwise the package will not be reloaded
package.loaded['mpack'] = nil
require('mpack')
$ lua demo.lua
lua: attempt to index a mpack.NIL value

Это также происходит с busted, потому что busted очищает кеш пакетов между тестами:

Изоляция тестовой среды сохраняет глобальную таблицу _G и все загруженные в данный момент пакеты package.loaded, восстанавливая их в исходное состояние по завершении блока insulate.

По умолчанию каждый тестовый файл запускается в отдельном блоке insulate, который можно отключить с помощью флага --no-auto-insulate.

Итак, у вас есть несколько вариантов:

  1. Используйте флаг busted --no-auto-insulate. Я бы не рекомендовал это делать, потому что это вообще отключает изоляцию.

  2. Используйте busted -e 'require("mpack")'. Выражение, переданное с аргументом -e, выполняется перед любыми тестами, поэтому механизм изоляции не удалит уже кэшированный пакет.

  3. Используйте expose block:

    -- spec/__init_spec.lua
    -- The name of this file is started with underscores to ensure that it will be processed
    -- before any other spec file. I don't know how to do it in a proper way (if it's possible).
    expose('preload mpack module', function()
        require('mpack')
    end)
    

См. https://olivinelabs.com/busted/#defining -тесты , раздел «Описать: изолировать и раскрыть блоки» для подробностей.

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

UPD: цитата из Lua справочного руководства о package.loaded:

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

https://www.lua.org/manual/5.3/manual.html#pdf -package.loaded

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...