【发布时间】:2021-04-11 01:56:35
【问题描述】:
我希望能够将我的脚本传递给.rakumod 文件的路径,比如<blah>/Mod.rakumod,并且能够像使用used 模块一样访问符号表作为哈希:
模块:
$ cat Mod.rakumod
unit module Mod;
sub bag is export { ... }
use lib <dir-containing-Mod>
use Mod;
say Mod::EXPORT::.keys
作为expected工作,返回(ALL DEFAULT)。
另一方面:
use lib <dir-containing-Mod>
require Mod;
say Mod::EXPORT::.keys
失败
Could not find symbol '&EXPORT' in 'Mod'
in block <unit> at <blah>
尽管事实上即使使用require,say Mod::.keys 确实会看到EXPORT:
use lib <dir-containing-Mod>
require Mod;
say Mod::.keys
---
(EXPORT Mod)
我需要使用require 来制作这个dynamic,因为我不知道我需要哪个模块。
其实我可以想到一件事情去做,但是绝对恶心:
- 将我的模块名称保存到变量
$mod - 让我的脚本编写另一个脚本
using 该模块:
my $mod = <whatever>
my $cd = qq:to/END/;
use v6;
use lib qq\|\$\*CWD\|;
use $mod;
say {$mod}::EXPORT::ALL::.keys;
END
'aux.p6'.IO.spurt($cd);
- 然后让初始脚本调用辅助脚本:
shell("raku aux.p6")
根据raiph's answer(我已接受并在此解释)有效的方法:
- 将路径传递给模块并保存为
$path; -
use lib相关目录:
my $dir = $path.IO.dirname;
use lib $dir;
- 提取纯文件名:
my $modFile = S/(.*)\..*/$0/ with $path.IO.basename;
- 最后,
require并从raiph's answer 中提取.WHO技巧,稍作改编:
require ::($modFile);
say ::("{$modFile}::EXPORT::ALL").WHO.keys;
使用返回(&bag) 的<script> <path> 运行正常。
实际上,上面的方法不太适用:use lib $dir 会说$dir 为空,因为use lib 不是动态的。
所以我现在求助于没有吸引力的解决方案
- 将模块文件复制到临时目录
./TMP - 已致电
use './TMP'; - 然后在完成后删除该目录。
【问题讨论】:
-
如果你不知道你想要什么模块,那么你就不会做
require Mod,而是require ::("Mod"); -
我知道,但这不是重点:它仍然是
require,它不会让我以哈希的形式访问模块。这里我展示了一个简化版本,它不使用字符串变量来保存模块路径。