Lua 中的“主”函数?

2024-04-02

在 python 中,通常会定义一个 main 函数,以便允许脚本用作模块(如果需要):

def main():
    print("Hello world")
    return 0

if __name__ == "__main__":
    sys.exit(main())

在Lua中,这个习语if __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
> 

鉴于上述内容,我希望至少您知道自己的立场,即使这并不完全是您的想法:)

Update:对于适用于 Lua 5.1 和 5.2 的 Hybrid.lua 版本,您可以将 getfenv 替换为 debug.getlocal:

if pcall(debug.getlocal, 4, 1) then
    print("Library")
else
    print("Main file")
end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lua 中的“主”函数? 的相关文章

  • 如何访问废弃的函数参数?

    在 Lua 中 调用带有多余参数的函数将简单地丢弃这些参数 有没有可能与debug库来访问这些被丢弃的参数 我不是在寻找可变参数函数 function test local info debug getinfo 1 u print info
  • Lua 如何创建可用于变量的自定义函数?

    对于像 io close 这样的方法 你可以像这样使用它 file close 有没有办法创建一个像这样工作的自定义函数 您可以在变量上调用它 对我来说 我尝试使用它通过使用 string find 查找空格来将参数与文本文件分开 所以在文
  • 我应该用 C++ 封装 Lua 代码的哪些代码?

    我终于将 LuaBind 配置为与我的 C 项目一起使用 我最近发现 Tiled 地图编辑器可以选择将文件导出为 lua 所以我想尝试一下 我将使用什么代码来封装下面粘贴的代码以使其与我的 C RPG 项目一起使用 return versi
  • 循环直到在表中找到 2 个特定值?

    我试图找到一种更聪明的方法来解决这个问题 这是与游戏相关的代码的摘录 它循环遍历每个背包的每个插槽 直到找到铲子和绳子 local continue local foundShovel foundRope for i 0 Container
  • 使用 corona sdk 验证电子邮件地址

    在我的项目中 有一个供用户填写详细信息的表单 其中有一个文本字段用于输入用户的电子邮件 ID 所以我需要在 corona 项目中验证该文本字段中的电子邮件 试试这个正则表达式 local email email protected cdn
  • 如何解密Lua字节码?

    早上好 我正在尝试破译 Moon 字节码 但我无法以任何方式 有人可以帮助我吗 我有这个 例如 code 27 76 117 97 81 0 1 4 4 4 8 0 如何将此字节码解密为文本 我已经在这里搜索 http www asciit
  • 为什么 LuaJIT 和 Lua 中的数字舍入格式不同?

    Using string format 据说遵循 Csprintf 在 LuaJIT 轮次中格式化数字与我尝试过的所有其他 Lua 解释器不同 lua v Lua 5 4 1 Copyright C 1994 2020 Lua org PU
  • Lua-迭代嵌套表

    我已经学习 Lua 几个星期了 这一次又一次成为我的症结所在 我尝试阅读有关该主题的帖子和书籍 我使用 Lua 查询软件监控系统 Nimsoft 我的数据以表格形式返回给我 我不会发布整个输出 但这里有一个我认为可以描述结构的片段 表参考是
  • lua_resume 的 from 参数的含义

    From Lua 5 2 参考手册 http www lua org manual 5 2 manual html lua resume int lua resume lua State L lua State from int nargs
  • lua中的权限问题

    是否需要在 corona build settings 中设置一些特定权限才能将高分永久保存在文件中 每次运行代码时都会出现 权限被拒绝 的错误 如何纠正这个错误 这是我尝试过的代码 function read score local f1
  • LuaJ 导入 Lua 方法

    我正在使用 LuaJ 并且我有一个 lua文件充满了一堆函数 如何通过 LuaJ 导入这些函数以在 Java 中使用 一种选择是将文件编译为 Java 代码并导入它 另一种方法是使用可嵌入解释器直接从 Java 代码中调用 Lua 文件 E
  • Lua中有状态迭代器和无状态迭代器的区别

    Lua中无状态和有状态迭代器有什么区别 请详细解释一下 什么时候需要使用无状态 什么时候需要使用另一种 我需要例子来理解这个概念 首先让我们就一个定义达成一致 在 Lua 中 迭代器是function 类似对象 每次调用时都会返回序列中的下
  • gsub 的转义字符串

    我读了一个文件 local logfile io open log txt r data logfile read a print data output n w r 1 2 n t x re S 是的 日志文件看起来很糟糕 因为它充满了各
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • Lua 上的 For 循环

    我的作业是如何执行 for 循环 我已经从数字上弄清楚了 但无法从名称上弄清楚 我想创建一个 for 循环来运行名称列表 以下是我到目前为止所拥有的 names John Joe Steve for names 1 3 do print n
  • 如何在 Lua - Lightroom 插件中使用 HMAC

    首先我要提的是我对 Lua 真的很陌生 如果你认为我的问题太愚蠢 请耐心等待 这是我的要求 我需要使用 HMAC sha256 进行 Lightroom 插件开发 因为我使用它是为了安全 我试图使用这个但没有运气https code goo
  • 在 Lua 中只归档一次

    我想知道是否有一种方法可以只执行一次 lua 文件 并且后续尝试执行该 lua 文件将导致无操作 我已经考虑过做一些类似于 C header 的 if else endif 技巧的事情 我想知道是否有一个标准方法来实现这一点 James w
  • Tarantool 中的冲突解决(如何在发生冲突时修复主-主模式下的复制)

    在多master场景下使用Tarantool如何实现冲突解决 我正在开发一项应该具有高可用性的服务 因此决定使用 nginx 作为 tarantool 两个节点 禁用只读选项 的负载均衡器 带有备份指令 它会重试对其他节点的失败请求 但如果
  • 表长度运算符的性能

    卢阿有 运算符来计算用作数组的表的 长度 在诸如 C 之类的语言中 计算出某个内容的长度后 通常不会再次计算它 例如int len strlen string 这在 Lua 中有什么不同吗 其中一个的效率是否比另一个低 显然这可能不会显示显
  • 模式 ^u.meta(\.|$) 未按预期工作

    我有这个模式 u meta 预期行为 u meta 将匹配所有角色 例如 u meta u meta admin u meta admin system u meta 它不应该匹配如下所示的内容 u meta admin u meta ad

随机推荐

  • 有什么方法可以检查是否强制执行严格模式?

    无论如何 是否要检查是否强制执行严格模式 use strict 并且我们希望为严格模式执行不同的代码 为非严格模式执行其他代码 寻找类似的功能isStrictMode boolean 事实是this在全局上下文中调用的函数内部不会指向全局对
  • HAProxy 随机空响应

    我安装了 HAPROXY 以实现两台服务器之间的平衡 不幸的是 HAPROXY 返回随机 ERR EMPTY RESPONSE 我也安装了统计信息 但统计信息没有出现频繁地因为有时会显示统计数据 我和一些朋友仔细检查了我的配置 没有发现问题
  • 从提升的子进程获取错误和标准输出

    我创建了一个进程处理程序 它启动两种类型的进程 使用管理员用户名和密码提升的权限 另一种无需输入任何用户名和密码即可正常运行 我正在努力弄清楚如何从提升的进程中获取输出 启动进程的应用程序不需要管理员凭据即可运行 管理员凭据输入到单独的加密
  • Angular2 i18n 用于占位符文本

    有没有办法使用 Angular 2 的 i18n 翻译输入文本字段的占位符文本
  • 从派生类访问基类公共成员

    是否可以从程序中其他位置的派生类实例访问基类公共成员 class base public int x base int xx x xx class derived base public derived int xx base xx cla
  • 从python句子中删除非英语单词

    我编写了一个代码 用于向 Google 发送查询并返回结果 我从这些结果中提取片段 摘要 以进行进一步处理 然而 有时这些片段中会出现我不想要的非英语单词 例如 u02b0w u025bn w u025bn unstressed u02b0
  • 多次按下按钮时声音重叠

    当我按下一个按钮 然后按下另一个按钮时 声音会重叠 我该如何解决这个问题 以便在按下另一个声音时第一个声音停止 void playOnce NSString aSound NSString path NSBundle mainBundle
  • ORA-01840: 输入值对于 Oracle Insert 使用 Select 中的日期格式来说不够长

    我有以下查询 其中出现错误ORA 01840 input value not long enough for date format The C DATE列是日期数据类型 INSERT INTO CS LOG NAME ID C DATE
  • React.PropTypes.func.isRequired 的问题

    我是 React 新手 正在尝试定义 PropTypes 但似乎它不再起作用 以下是我如何使用它 React PropTypes func isRequired Below is the error am getting 那么这就是我所缺少
  • 是否可以检查 CSS 变量是否已定义?

    我想知道是否可以仅在定义了 css 变量的情况下应用 CSS 规则 我已经看到可以定义默认值 例如 background color var bgColor red 但我认为这不会在我的项目中起作用 因为我想要的是 当未定义变量来获取该行在
  • Conda - 从防火墙后面的 .whl 文件安装tensorflow

    我有一个Anaconda3 与 Python 3 6 Spyder 环境 正在尝试安装tensorflow但是 由于公司防火墙的原因 无法使用标准的 pip 安装 此外 出于同样的原因 我无法创建 anaconda 环境 我想做的是直接从安
  • Levene 检验的多重比较事后检验

    我想在 R 中对 Levene 的测试进行成对比较事后测试 我知道如何使用 PROC GLM 在 SAS 中执行此操作 但我似乎不知道如何在 R 中执行此操作 有人有吗主意 在下面的示例中 我希望能够测试所有 猫 级别 即 A B A C
  • Scala 中的无符号变量

    我正在将一些 C 代码转换为 Scala 因为我们正在 据称 进入企业大厦的现代世界 至少我是被告知的 某些 C 代码使用无符号变量 这些变量对其执行了大量位级 移位 操作 我对如何将它们转换为 Scala 完全处于停滞状态 因为我相信 S
  • PrimeFaces。渲染后更新数据表

    我有一个数据表并想要保留过滤器 我可以保存过滤器值并通过调用数据表将它们放回 我将过滤器值放回到渲染中 现在我想要过滤表 是的 我想调用服务并从中获取所有数据 然后我想使用保留在过滤字段中的值来过滤表 我找不到在渲染表格后启动过滤的解决方案
  • 线程可以处理很长的 I/O 进程吗

    我在这里开始一个新主题 该主题将与这个问题 https stackoverflow com questions 47250025 qthreadpool how to interrupt how to use wisely the wait
  • 将 Psyco 移植到 64 位可能存在哪些陷阱?

    心理医生说 仅供参考 Psyco 不 可以在任何 64 位系统上工作 这个事实值得再次注意 现在最新的 Mac OS X 10 6 雪豹 自带默认 64 位上的 64 位 Python 机器 使用 Psyco 的唯一方法 OS X 10 6
  • 在 CSS 中将文本垂直和水平居中在圆圈中(如 iphone 通知徽章)

    我正在寻找一种在 CSS3 中制作类似 iphone 的跨浏览器徽章的方法 我显然想使用一个 div 来实现这一点 但其他解决方案也可以 重要的因素是它需要在所有浏览器中水平和垂直居中 关于这些通知的一个有趣的设计问题是它们不能具有指定的宽
  • 如何解析/proc/pid/cmdline

    我试图在 Linux 上拆分进程的命令行 但似乎我不能依赖它用 0 字符分隔 你知道为什么有时 0 字符用作分隔符而有时它是常规空格吗 您知道检索可执行文件名称及其路径的其他方法吗 我一直在尝试使用 ps 获取此信息 但它总是返回完整的命令
  • C++11 嵌套宏调用?

    它在 C std 16 3 4 中说 生成的预处理标记序列 来自宏调用替换 与源文件的所有后续预处理标记一起重新扫描 以获取更多宏名称 代替 如果在替换列表扫描期间找到了被替换的宏的名称 不包括 源文件的其余预处理标记 它不会被替换 此外
  • Lua 中的“主”函数?

    在 python 中 通常会定义一个 main 函数 以便允许脚本用作模块 如果需要 def main print Hello world return 0 if name main sys exit main 在Lua中 这个习语if n