如何要求带有名称中带有点的文件?

huangapple go评论68阅读模式
英文:

How to require a file with a dot in the name?

问题

我正在尝试使用 "config/lsp.rc.lua",但使用 require("config.lsp.rc") 会导致错误。

英文:

I am trying to require "config/lsp.rc.lua", but doing require("config.lsp.rc") gives an error.

答案1

得分: 0

以下是翻译好的部分:

问题很简单:负责的require加载器将使用目录分隔符(Unix上的/)替换每个点。

请注意,不应在require中使用/,因为它是特定于平台的目录分隔符(实际上,Windows也会支持它)。

您最好的选择是简单地重命名文件,将点替换为下划线或类似的方式,以遵循Lua的约定。

但是,如果这超出了您的控制范围,您还可以对require进行猴子补丁以支持您的用例。

我们可以使用/代替.作为目录分隔符。

为此,我们必须实现自己的搜索器:

这个表中的每个条目都是搜索器函数。在查找模块时,require按升序调用这些搜索器中的每一个,其参数是模块名称(提供给require的参数)。如果搜索器找到了模块,它将返回另一个函数,即模块加载程序,以及一个额外的值,加载程序数据,它将传递给加载程序,并由require作为第二个结果返回。如果找不到模块,它将返回一个解释为为什么找不到的字符串(或者如果没有什么可说的话,则返回nil)。

幸运的是,我们可以利用package.searchpath来为我们完成大部分工作:

local function searcher(module_name)
    -- 使用"/"代替".作为目录分隔符
    local path, err = package.searchpath(module_name, package.path, "/")
    if path then
        return assert(loadfile(path))
    end
    return err
end

现在我们只需将其插入到package.searchers中,以供require使用。我们可以将其插入到首位、末位或任何位置,都无所谓,所以让我们将其插入到末位,以便仅当所有内置搜索器失败时才尝试我们的搜索器:

table.insert(package.searchers, searcher)

用法:

local lsp_rc = require("config/lsp.rc")

然后将按预期工作。

如果您不希望全局修补require,您可以实现一个本地的require,只在Lua路径中搜索,使用您的约定:

local function myrequire(module_name)
    return assert(loadfile(assert(package.searchpath(module_name, package.path, "/")))
end
local lsp_rc = myrequire("config/lsp.rc")
英文:

The problem is simple: The responsible require loader will replace each dot with the directory separator (/ on Unix).

Note that you should not use / in require since it is a platform-specific directory separator (in practice it will be supported by Windows though).

Your best option would be to simply rename the file, replacing the dot with an underscore or the like to abide by Lua's conventions here.

However, if this is out of your control, you may also monkey-patch require to support your use case.

Instead of using . as directory separator, we may use /.

For that, we have to implement our own searcher:

> Each entry in this table is a searcher function. When looking for a module, require calls each of these searchers in ascending order, with the module name (the argument given to require) as its sole argument. If the searcher finds the module, it returns another function, the module loader, plus an extra value, a loader data, that will be passed to that loader and returned as a second result by require. If it cannot find the module, it returns a string explaining why (or nil if it has nothing to say).

Luckily we can leverage package.searchpath to do most of the work for us:

local function searcher(module_name)
    -- Use "/" instead of "." as directory separator
    local path, err = package.searchpath(module_name, package.path, "/")
    if path then
        return assert(loadfile(path))
    end
    return err
end

Now we just have to pluck this into package.searchers for require to use it. We could insert it first, last, wherever, doesn't matter, so let's insert it last, such that only if all builtin searchers fail our searcher is tried:

table.insert(package.searchers, searcher)

Usage:

local lsp_rc = require("config/lsp.rc")

will then work as expected.

If you do not want to globally patch require, you could implement a local require that just searches in the Lua path, using your conventions:

local function myrequire(module_name)
    return assert(loadfile(assert(package.searchpath(module_name, package.path, "/"))))
end
local lsp_rc = myrequire("config/lsp.rc")

huangapple
  • 本文由 发表于 2023年2月18日 07:30:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75490124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定