Как получить точный путь к скрипту, который был загружен в Lua? - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь выполнить «горячую перезагрузку» lua файлов, пока я над ними работаю.

Моя проблема в том, что я не знаю, как сопоставить файл, который изменился, с записями в таблице package.loaded. Хотя я могу это догадаться, мне было интересно, хранится ли где-нибудь полный путь.

Учитывая файл с именем mymodule.lua, когда мы запускаем это:

local x = require('mymodule')

Сначала lua выглядит в package.loaded чтобы увидеть, загружен ли он уже. Если нет, то Lua ищет модули, используя LUA_PATH, который мы можем видеть во время выполнения следующим образом:

> print(package.path)
/usr/share/lua/5.3/?.lua;/usr/share/lua/5.3/?/init.lua;/usr/lib64/lua/5.3/?.lua;/usr/lib64/lua/5.3/?/init.lua;./?.lua;./?/init.lua

После загрузки вышеуказанного модуля мы можем видеть, что он загружен, ища это в таблице package.loaded примерно так:

> for i,v in pairs(package.loaded) do
>> print(i, v)
>> end
debug   table: 0x55fa3bfe8b80
table   table: 0x55fa3bfe51e0
math    table: 0x55fa3bfe7820
mymodule    table: 0x55fa3bfe60f0
_G  table: 0x55fa3bfe2bc0
utf8    table: 0x55fa3bfe8700
bit32   table: 0x55fa3bfe9070
os  table: 0x55fa3bfe68f0
package table: 0x55fa3bfe4860
io  table: 0x55fa3bfe54e0
coroutine   table: 0x55fa3bfe4f90
string  table: 0x55fa3bfe7560

Мой подход к обработке горячей перезагрузки состоит в том, чтобы обнулить запись в этой таблице package.loaded.mymodule = nil, а затем снова загрузить скрипт, например, require('mymodule') Кажется, работает нормально - модуль перезагружается.

Но тогда есть предостережения ... Например, если модуль на самом деле настроен как myproject/mymodule/init.lua, и это загружается как require('mymodule'), то запись в таблице package.loaded просто будет mymodule, и в этом случае ничего более полезного, например, mymodule/init.lua, я не могу знать, что мне нужно смотреть файл init.lua вместо mymodule.lua

В этом случае я отслеживаю файлы в C. Моя проблема в том, что мне нужно как-то угадать, какая запись в таблице package.loaded соответствует какому файлу.

Что я хотел бы знать, так это то, что где-то есть таблица, содержащая путь к чему-либо. lua файлы загружены, так что я могу просто следить за этим списком.

Может быть, package.loaded - это не то место, где нужно искать?

1 Ответ

2 голосов
/ 18 февраля 2020

Можно изменить два поисковика для сбора путей к файлам модуля в таблицу package.loadedfrom

-- this block should be at the beginning of the main script
do
   assert(_VERSION:match"^Lua 5%.[2-4]$")  -- only for Lua 5.2+
   package.loadedfrom = {}

   local function save(modname, loader, path)
      if type(loader) == "function" then
         package.loadedfrom[modname] = path
      end
      return loader, path
   end

   local orig_searcher_2 = package.searchers[2]
   package.searchers[2] =
      function(modname)
         return save(modname, orig_searcher_2(modname))
      end

   local orig_searcher_3 = package.searchers[3]
   package.searchers[3] =
      function(modname)
         return save(modname, orig_searcher_3(modname))
      end
end

-- now require all your modules
require"mymodule"
require"mymodule2"

-- now get the list of module file paths
for modname, filepath in pairs(package.loadedfrom) do
   print(modname, filepath)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...