【问题标题】:Unable to require in Lua无法在 Lua 中要求
【发布时间】:2021-10-11 01:00:12
【问题描述】:

我对require的理解如下: 如果您需要的文件位于您需要的同一目录中,或者位于package.path 中,您就可以使用它。

然而,对我来说,即使文件位于同一目录中,我也会收到 Module not found! 错误。

至于package.path,我的电脑上不存在列出的目录。这是我的package.path

/usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/local/lib/lua/5.2/?.lua; /usr/local/lib/lua/5.2/?/init.lua;/usr/share/lua/5.2/?.lua;/usr/share/lua/5.2/?/init.lua;./?.lua

除了我为不同目的创建的文件夹外,我的电脑(我可以找到)上没有名为“lua”的文件夹。这使我怀疑安装错误,尽管我确实尝试卸载 Lua 并得到了Virtual packages like 'lua' can't be removed。这可能是相关的,我不确定。但除了无法 require 模块和缺少名为 'lua' 的目录之外,一切正常。

此时我不知道该怎么做。除了“附加到您的package.path!”之外,我找不到关于该主题的更多信息。但我宁愿能够简单地将上述两个文件放在同一个目录中以使其正常工作。

我该如何解决这个问题?

我还有一个小问题:lua 是否有默认模块/包?

编辑:
操作系统 - Ubuntu Linux
Lua 版本 - 5.2
我正在运行foo = require('bar')
我不是要一个二进制模块,我是要一个我写的 lua 文件。

【问题讨论】:

    标签: lua


    【解决方案1】:

    使用 dofile("path/to/file.lua")

    【讨论】:

      【解决方案2】:

      当我开始 require() 文件时,你的理解和我一样差。
      现在我明白了(Lua for Linux)...

      1. require() 第一次看package.loaded
      2. 如果不存在,它会在以下位置查找加载器函数:package.preload
      3. 如果 1. 和 2. 失败,那么它将尝试搜索路径:*.lua(Lua 代码)*.bin(Lua 字节码)和 *.so(库)

      我对 require() 的建议是编写一个 package.preload 函数,该函数在 package.loaded 中返回您想要的内容。
      因为您可以使用其中的完整路径或相对路径执行 loadfile()dofile()
      这不需要修改 package.path。
      因此,也可以在不将目录更改到主脚本位置的情况下启动主脚本。

      package.preload 函数的示例...

      -- A loader for require('test')
      package.preload.test=function() return {test='test'} end
      -- Now require it...
      newtable=require('test')
      -- Using it...
      print(newtable.test) -- Puts out: test
      

      loadfile() 的预加载函数示例

      -- Add a loader for require('rot')
      package.preload.rot=loadfile('/home/knoppix/lua/rot.lua')
      

      如果您查看以下内容,您的第二个问题是自我回答:package.loaded
      正如我写的 require() 看起来首先在那里。
      试试看……

      _G=empty -- Deleting _G
      -- Now reinstall it simply by...
      _G=require('_G')
      -- It will be restored from: package.loaded
      

      【讨论】:

        【解决方案3】:

        您可以尝试将文件作为字符串读取,然后编译并执行该字符串。例如:

        --Instead of writing "require 'mymodule'" you can say:
        
        
        --Read the file contents
        local f=io.open("mymodule.lua","r")
        local s = f:read("*a")
        
        --loadstring compiles a chunk of code and returns a function. On some Lua versions though, loadstring isn't defined, and so, you can use load (same thing, different name)
        
        loadstring = loadstring or load
        
        loadstring(s)()
        
        --Close the file object
        f:close()
        

        你可以把它变成一个函数:

        loadstring = loadstring or load
        
        function myrequire(modulename)
            f = io.open(modulename,"r")
            loadstring(f:read("*a"))()
            f:close()
        end
        

        其实也有类似的东西,叫做“dofile”。它与“myrequire”的效果完全相同。

        注意: 这些东西可能会完成你的工作,但你应该知道,require 与 dofile 并不完全相同。不同之处在于,require 不仅查看当前目录,还查看“package.path”变量指定的目录。此外,require 将所有加载的模块存储在“package.loaded”中,这样​​当您尝试多次加载同一个模块时它会更快。

        【讨论】:

          【解决方案4】:

          您没有提供足够的信息来帮助您,因为您没有指定您正在使用的 Lua 版本(我猜从文件路径来看是 5.2),操作系统(Linux?),实际的 @987654321 @ 你正在执行的命令或你需要的 lua 文件的位置相对于你需要它的文件的位置,等等。

          您的假设是正确的,但可能有多个问题会阻止您加载文件。例如,它可能位于正确的位置,但您使用的不是require "foo",而是require "foo.lua",这是行不通的。或者您正在尝试加载二进制模块(不会受到package.path 配置的影响)。或者您正在加载的模块存在不满足的依赖关系。

          是否有 lua 自带的默认模块/包?

          是的,例如debugmathio 等,但您不会将它们视为 Lua 文件,因为它们与 Lua 解释器的其余部分一起编译为 C 模块。

          【讨论】:

          • 我更新了帖子以包含我遗漏的信息。道歉!正如我在帖子中所说,当两个文件位于同一目录中时会发生此错误。我没有费心尝试将包/模块/必需文件移动到另一个目录或将任何内容附加到package.path
          • 您显示的路径确实包含对当前目录 (./?.lua) 的引用,因此它应该能够存放您需要的文件。您是否还可以包含来自“require”的完整错误消息,因为它应该显示所有路径都已尝试过,并且在此故障排除中应该非常有用。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-17
          • 1970-01-01
          • 2012-11-15
          • 1970-01-01
          • 2015-02-19
          • 1970-01-01
          相关资源
          最近更新 更多