Нет «правильного» способа сделать это, так как Lua на самом деле не различает код по происхождению, все они просто функции. Тем не менее, это, по крайней мере, кажется, работает в Lua 5.1:
matthew@silver:~$ cat hybrid.lua
if pcall(getfenv, 4) then
print("Library")
else
print("Main file")
end
matthew@silver:~$ lua hybrid.lua
Main file
matthew@silver:~$ lua -lhybrid
Library
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> ^C
matthew@silver:~$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require "hybrid"
Library
> ^C
matthew@silver:~$
Он работает, проверяя, превышает ли глубина стека 3 (нормальная глубина для файла в стандартном интерпретаторе Lua). Однако этот тест может нарушаться между версиями Lua и даже в любых встроенных / пользовательских сборках Lua.
Я также включу эту (немного более переносимую) альтернативу, хотя она делает еще больший скачок в эвристике и имеет случай сбоя (см. Ниже):
matthew@silver:~$ cat hybrid2.lua
function is_main(_arg, ...)
local n_arg = _arg and #_arg or 0;
if n_arg == select("#", ...) then
for i=1,n_arg do
if _arg[i] ~= select(i, ...) then
print(_arg[i], "does not match", (select(i, ...)))
return false;
end
end
return true;
end
return false;
end
if is_main(arg, ...) then
print("Main file");
else
print("Library");
end
matthew@silver:~$ lua hybrid2.lua
Main file
matthew@silver:~$ lua -lhybrid2
Library
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> ^C
matthew@silver:~$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require "hybrid2"
Library
>
Этот метод работает путем сравнения содержимого _G.arg с содержимым '...'. В основной части они всегда будут одинаковыми. В модуле _G.arg по-прежнему будет содержать аргументы командной строки, но «...» будет содержать имя модуля, переданное require (). Я подозреваю, что это ближе к лучшему решению для вас, учитывая, что вы знаете название вашего модуля. Ошибка в этом коде заключается в том, что пользователь выполняет основной скрипт с 1 аргументом, и это точное имя вашего модуля:
matthew@silver:~$ lua -i hybrid2.lua hybrid2
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
Main file
> require "hybrid2"
Main file
>
Учитывая вышесказанное, я надеюсь, что, по крайней мере, вы знаете, где вы находитесь, даже если это не совсем то, что вы имели в виду:)
Обновление: Для версии hybrid.lua, которая работает в Lua 5.1 и 5.2, вы можете заменить getfenv на debug.getlocal:
if pcall(debug.getlocal, 4, 1) then
print("Library")
else
print("Main file")
end