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 表.concat

    有没有办法使用table concat的arg 2值来表示当前表索引 eg t t 1 a t 2 b t 3 c X table concat t n 表 concat X 的所需输出 1 a n2 b n3 c n 简单的回答 不 ta
  • Lua:setfenv() 与 _ENV

    Lua 切换有什么大不了的setfenv to ENV 在各种 新增内容 资料中 这一举措被认为是 Lua 5 1 和 5 2 版本之间最重要的变化之一 但是 PIL 和其他地方给出的示例可以修剪为以下内容 Lua 5 1 Lua 5 2
  • 用于数据存储的 Lua 与 XML

    我们中的许多人都被灌输了使用 XML 来存储数据的观念 它的优点和缺点众所周知 我当然不想在这里讨论它们 然而 在我用 C 编写的项目中 我也使用 Lua 我非常惊讶 Lua 能够如此出色地存储和处理数据 然而 Lua 的这一方面却鲜为人知
  • 寻找 Lua 4.1 alpha

    我正在帮助为一款相当老的游戏 孤岛惊魂 开发多人模式 我想编译lua代码 但游戏使用版本4 1 alpha 我在任何地方都找不到 lua 4 1 alpha tar gz http www lua org work old lua 4 1
  • 从lua中的函数返回多个值

    我正在尝试以下 lua 代码 function test return 1 2 end function test2 return test end function test3 return test 3 end print test p
  • 如何在 Lua 中下载文件,但在运行时写入本地文件

    我正在尝试制作一个更新程序 以便当我的 Lua 应用程序过时时它将使用LuaSocket下载较新的 exe 文件 可以运行我的 Lua 代码 在这个更新程序中 我希望它显示到目前为止已下载的数量 但是 通过以下 HTTP 请求 它会阻止应用
  • 代码说“尝试比较数字<=实例”

    It says Players ninjafox56 PlayerGui Shop ShopGui LightSide ChooseSideL 5 尝试比较数字 Rank game Players LocalPlayer leadersta
  • 在 lua 中使用相等运算符比较数字有多安全?

    在我的引擎中 我有一个用于脚本编写的 Lua VM 在脚本中 我写了这样的内容 stage stage 1 if stage 5 then end and objnum tonumber 5 if stage objnum 根据 Lua 来
  • LuaJit FFI 从 C 函数返回字符串到 Lua?

    假设我有这个 C 函数 declspec dllexport const char GetStr static char buff 32 Fill the buffer with some string here return buff 这
  • 如何在多个Lua State(多线程)之间传递数据?

    我在中启动Redis连接池redis lua 通过从 C 调用 我得到了redis lua state 此 Lua 状态全局启动一次 仅在其他线程中启动get从中 当有一个 HTTP 请求 工作线程 时 我需要从redis lua stat
  • 什么更快?循环或多个 if 条件

    我想知道什么更快 是只用一条指令 即 1 1 执行 9 次 for 循环还是执行 9 个 if 条件时 我认为 if 更快 因为您不需要检查循环中的指令 它应该几乎相同 因为for循环本质上是检查if条件为真并运行一段代码 非常类似于if声
  • 在 Corona sdk 上保存高分?

    我想保存游戏中创建的高分 并且当玩家点击高分按钮时可以在主菜单中看到 有人可以帮助我吗 您可以使用SQLITE https docs coronalabs com api library sqlite3 index html将高分保存到数据
  • Redis 排序集和解决关系

    我正在使用 Redis 排序集来存储我正在处理的项目的排名 我们没有预料到 我们想要如何处理关系 Redis 按字典顺序对具有相同分数的条目进行排序 但我们想要做的是对具有相同分数的所有条目给予相同的排名 例如在以下情况 redis 127
  • Lua-迭代嵌套表

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

    我已经成功为 API 安装了 kong 网关 该 API 通过上游负载平衡到多个目标 应用程序服务器 现在 我有一个我的应用程序服务器的自签名证书 kong 和目标之间的 ssl 握手应该失败 我推断 kong 不验证上游证书 经过一些研究
  • Lua userdata:无法同时进行数组访问和方法

    我遇到了这个人的问题 Lua userdata数组访问及方法 https stackoverflow com questions 26970316 lua userdata array access and methods 其中 当我设置用
  • 如何在Conky中实现一个基本的Lua功能?

    我正在尝试向我的 Conky 添加一个函数 该函数打印字符串的长度以用于调试目的 代码位于名为的文件内test lua 非常简单 function test word return string len word end 我这样加载它 在我
  • Lua中如何在另一个表的表成员中搜索

    我正在编写一个 lua 程序 它有一个表 该表是另一个表的成员 当我向该成员表添加新日期时 一切正常 但是 当我想在该表中搜索时 无论我给出什么键 我总是会将最后一行添加到表中 如何在该成员表中正确搜索 Stream name functi
  • Lua 将字符串转换为数字 - 取决于语言环境

    刚刚注意到字符串 and tonumber 在 Lua 中是依赖于语言环境的 知道如何在不使用的情况下将字符串转换为数字tonumber 谢谢 例如将字符串 58 5 转换为 58 5 另外 当我尝试将带点的数字传递给函数时 该函数会转换
  • Lua 访问表的键和值

    我想在关卡编辑器中读取 Lua 文件 这样我就可以以可视化格式显示其数据供用户编辑 如果我有一个像这样的 Lua 表 properties Speed 10 TurnSpeed 5 Speed显然是关键并且10价值 我知道如果我知道像这样的

随机推荐

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

    无论如何 是否要检查是否强制执行严格模式 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