如何在Raku中实现Perl5 FindBin式的脚本相对路径模块加载?
在Raku中实现相对路径加载本地模块(对应Perl的FindBin场景)
刚好我之前处理过类似的需求,Raku里其实有很直接的方式实现,完全符合你要求的不用环境变量、不用zef安装、支持任意目录运行脚本的场景,具体实现如下:
核心实现代码
在你的p.raku脚本开头加上这两行:
use lib $*PROGRAM.parent.Str; use Mod;
然后就可以正常调用Mod模块里的内容了,比如:
# 示例:调用Mod模块中的子例程 Mod::greet("World");
对应的Mod.rakumod可以是这样的简单模块:
unit module Mod; sub greet($name) is export { say "Hello, $name!"; }
为什么这能生效?
$*PROGRAM是Raku内置的特殊变量,它是一个IO::Path对象,指向当前正在运行的脚本文件(不管你从哪个目录启动脚本)。.parent方法会获取这个脚本文件所在的目录,.Str把路径对象转换成字符串格式,方便use lib识别。use lib会把指定的目录添加到Raku的模块搜索路径@*INC中,这样后续的use Mod就能找到同目录下的Mod.rakumod文件。
验证两种运行场景
在脚本所在目录运行:
假设脚本在d1目录下,进入该目录后执行:rakudo p.raku此时
$*PROGRAM.parent就是d1目录,能正常加载Mod.rakumod。在上级目录运行脚本:
从d1的上级目录执行:rakudo d1/p.raku这里
$*PROGRAM依然指向d1/p.raku,.parent还是d1目录,所以同样能找到模块。
额外注意点
- 确保模块文件名和
use的名称一致:比如use Mod对应Mod.rakumod,如果模块名是My::Mod,那文件要放在My/Mod.rakumod,同时use lib要指向My目录的父目录。 - 这种方式完全是本地加载,不需要把模块发布到zef仓库,也不需要设置
RAKULIB之类的环境变量。
内容的提问来源于stack exchange,提问作者Konrad Eisele
相关产品推荐
相关产品推荐

