在python中,通常会定义一个主要功能,以便将脚本用作模块(如果需要): def main(): print("Hello world") return 0if __name__ == "__main__": sys.exit(main()) 在Lua中,如果__name__ ==“__main__”的成语是不可
def main():
print("Hello world")
return 0
if __name__ == "__main__":
sys.exit(main())
在Lua中,如果__name__ ==“__main__”的成语是不可能的(这意味着我不认为是这样)。
这就是我通常在为了在Lua中有类似的行为而做的:
os.exit((function(args)
print("Hello world")
return 0
end)(arg))
但是这种方法似乎比较重“括号”:-)
有更常见的方法(除了定义一个全局主要功能,这似乎是多余的)?
没有“适当”的方式来做,因为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 >
鉴于上述,我希望至少你知道你站在哪里,即使这不是你所想的:)
更新:对于在Lua 5.1和5.2中工作的hybrid.lua版本,您可以使用debug.getlocal替换getfenv:
if pcall(debug.getlocal, 4, 1) then
print("Library")
else
print("Main file")
end
