首页 > 解决方案 > 如何在 Raku 运行时动态访问模块的符号表?

问题描述

我希望能够将我的脚本传递给.rakumod文件的路径,例如<blah>/Mod.rakumod,并且能够以哈希的形式访问符号表,就好像我要use使用模块一样:

模块:

$ cat Mod.rakumod
unit module Mod;
sub bag        is export             { ... }
use lib <dir-containing-Mod>
use Mod;
say Mod::EXPORT::.keys

预期工作,返回(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来制作这个动态,因为我不知道我想要哪个模块。


我其实可以想到一件事情来做,但这绝对是恶心:

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 的回答(我已经接受并在这里解释),什么有效:

my $dir = $path.IO.dirname;
use lib $dir;
my $modFile = S/(.*)\..*/$0/ with $path.IO.basename;
require ::($modFile);
say ::("{$modFile}::EXPORT::ALL").WHO.keys;

运行与<script> <path>返回(&bag)没关系。


实际上,上面的方法不太有效:说是空的use lib $dir会失败,因为它不是动态的。$diruse lib

所以相反,我现在求助于没有吸引力的解决方案

标签: moduleraku

解决方案


TL;DR使用动态符号查找在运行时获取所需符号的包的符号;然后.WHO得到它的藏匿处;然后.keys得到那个藏匿处的符号。

例如:

use lib '.';
require Mod;
say ::Mod::EXPORT::('ALL').WHO.keys; # (&bag)

我要去做早餐了。我稍后会详细说明。


推荐阅读