module - 如何在 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
来制作这个动态,因为我不知道我想要哪个模块。
我其实可以想到一件事情来做,但这绝对是恶心:
- 将我的模块名称保存到变量中
$mod
- 让我的脚本为该模块编写另一个脚本:
us
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 的回答(我已经接受并在这里解释),什么有效:
- 将路径传递给模块并将其另存为
$path
; use lib
相关目录:
my $dir = $path.IO.dirname;
use lib $dir;
- 提取纯文件名:
my $modFile = S/(.*)\..*/$0/ with $path.IO.basename;
- 最后,从raiph 的回答
require
中提取诀窍,稍作改编:.WHO
require ::($modFile);
say ::("{$modFile}::EXPORT::ALL").WHO.keys;
运行与<script> <path>
返回(&bag)
没关系。
实际上,上面的方法不太有效:说是空的use lib $dir
会失败,因为它不是动态的。$dir
use lib
所以相反,我现在求助于没有吸引力的解决方案
- 将模块文件复制到临时目录
./TMP
- 打过电话
use './TMP';
- 然后在完成后删除该目录。
解决方案
TL;DR使用动态符号查找在运行时获取所需符号的包的符号;然后.WHO
得到它的藏匿处;然后.keys
得到那个藏匿处的符号。
例如:
use lib '.';
require Mod;
say ::Mod::EXPORT::('ALL').WHO.keys; # (&bag)
我要去做早餐了。我稍后会详细说明。
推荐阅读
- bootstrap-4 - 为什么这个引导代码不适用于嵌套行?
- ios - 如何在 segue 之前等待函数完成并更新 tableview。iOS 斯威夫特
- python - Python:尝试从另一个编码 .py 文件导入模块时出现“ModuleNotFoundError”
- file - electron sheetjs 从 JSON 下载生成的文件
- json - 带有 ppx_deriving_yojson 的 sum 类型变体的自定义 json 生成器
- tfs - TFS 2018 PAT 令牌和 AD 帐户密码更改?
- wpf - 尝试获取 Text.IsEmpty 或 Text.IsNullOrEmpty 属性的数据触发器
- python - 仅展开函数所需的键值对
- ios - 如何为 GMSMarker 设置动画?
- elasticsearch - 如何对 Elasticsearch 中的对象列表执行聚合(例如 avg)?