搜索路径

简介: 搜索路径

在搜索一个 Lua 文件时,函数 require 使用的路径与典型的路径略有不同。典型的路径是很多目录组成的列表,并且在其中搜索指定文件。不过, ISO CLua 语言依赖的抽象平台)并没有目录的概念。所以,函数 require 使用的路径是一组模板,其中的每项都指定了将模块名(函数 require 的参数)转换为文件名的方式。更准确的说,这种路径中的每一个模板都是一个包含可选问号的文件名。对于每个模板,函数 require 会用模块名来替换每一个问号,然后检查结果是否存在对应的文件。如果不存在,则尝试下一个模板。路径中的模板以在大多数操作系统中很少被用于文件名的分号隔开。例如,考虑如下路径:

?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua


在使用这个路径时,调用 require "sql" 将尝试打开如下的 Lua 文件:

  • sql
  • sql.lua
  • c:\windows\sql
  • /usr/local/lua/sql/sql.lua


函数 require 只处理分号(作为分隔符)和问号,所有其他的部分(包括目录分隔符和文件扩展名)则由路径自己定义。


函数 require 用于搜索 Lua 文件的路径是变量 package.path 设置成环境变量 LUA_PATH_5_3 的值。如果这个环境变量没有被定义,那么 Lua 语言则尝试另一个环境变量 LUA_PATH 。如果这两个环境变量都没有被定义,那么 Lua 语言则使用一个编译时定义的默认路径。在使用一个环境变量的值时, Lua 语言会将其中所有的" ;; "替换成默认路径。例如,如果将 LUA_PATH_5_3 设为" mydir/?.lua;; ",那么最终路径就会是模板" mydir/?.lua "后跟默认路径。


搜索 C 标准库的路径的逻辑与此相同,只不过 C 标准库的路径来自变量 package.cpath 而不是 package.path 。类似地,这个变量的初始值也来自环境变量 LUA_CPATH_5_3LUA_CPATH 。在 POSIX 系统中这个路径的典型值形如:

./?.so;/usr/local/lib/lua/5.3/?.so


请这一定义文件扩展名的路径。在上例中,所有模板使用的都是 .so ,而在 Windows 操作系统中此典型路径通常形如:

.\?.dll;C:\Program Files\Lua503\dll\?.dll


函数 package.searchpath 中实现了搜索库的所有规则,该函数的参数包括模块名和路径,然后遵循上述规则来搜索文件。函数 package.searchpath 要么返回第一个存在的文件的文件名,要么返回 nil 外加描述所有文件都无法成功打开的错误信息,如下:

> path = ".\\?.dll;C:Program Files\\Lua503\\dll\\?.dll"
> print(package.searchpath("X", path))
nil
        no file '.\X.dll'
        no file 'c:\Program Files\Lua503\dll\X.dll'


作为一个有趣的练习,我们来实现一个与函数 package.searchpath 类似的函数

function search (modname, path)
  modname = string.gsub(modname, "%.", "/")
  local msg = {}
  for c in string.gmatch(path, "[^;]+") do
    local fname = string.gsub(c, "?", modname)
    local f = io.open(fname)
    if f then
      f:close()
      return fname
    else
      msg[#msg + 1] = string.format("\n\tno file '%s'", fname);
    end
  end
  return nil, table.concat(msg)   -- 没找到
end


上述函数首先替换目录分隔符,在本例中即把所有的点换成斜杠。之后,该函数遍历路径中的所有组成部分,也就是每一个不含分号的最长匹配。对于每一个组成部分,该函数使用模块名来替换问号得到最终的文件名,然后检查相应的文件是否存在。如果存在,该函数关闭这个文件,然后返回文件的名称;否则,该函数保存失败的文件名用于可能的错误信息(注意字符串缓冲区在避免创建无用的长字符串时的作用)。如果一个文件都找不到,该函数返回 nil 及最终的错误信息。

目录
相关文章
|
6月前
|
数据采集 存储 API
手动给docusaurus添加一个搜索
如果algolia不能自动配置的话,我教你手动给docusaurus添加一个搜索
手动给docusaurus添加一个搜索
|
数据采集 搜索推荐 前端开发
11、搜索服务
根据分类、关键字匹配课程名称,课程内容、难度等级搜索,搜索方式为全文搜索,搜索节点分页显示。
102 0
|
搜索推荐 安全 Java
搜索
搜索
117 0
|
Linux 数据库
Linunx搜索,查找类
1.Linux find 命令 Linux find 命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。 按文件名查找: 例如:查找服务器上所有名为hello.txt的文件:
133 0
|
机器学习/深度学习 算法 搜索推荐
DARTS+:DARTS 搜索为何需要早停?
近日,华为诺亚 方舟实验室的作者们提出一种可微分的神经网络架构搜索算法 DARTS+,将早停机制(early stopping)引入到原始的 DARTS[1] 算法中,不仅减小了 DARTS 搜索的时间,而且极大地提升了 DARTS 的性能。相关论文《DARTS+: Improved Differentiable Architecture Search with Early Stopping》已经公开(相关代码稍后也会开源)。
227 0
DARTS+:DARTS 搜索为何需要早停?
|
存储 缓存 自然语言处理
一切为了搜索
Elasticsearch是​ 基于Lucene搜索架构的一个分布式、RESTful 风格的搜索和数据分析引擎
|
缓存 Python Shell
Python模块搜索路径
当一个名为 spam 的模块被导入的时候,解释器首先寻找具有该名称的内置模块。如果没有找到,然后解释器从 sys.path 变量给出的目录列表里寻找名为 spam.py 的文件。sys.path 初始有这些目录地址: 包含输入脚本的目录(或者未指定文件时的当前目录)。
下一篇
无影云桌面