首页 > 解决方案 > 使用模块时如何避免导入默认符号?

问题描述

我将Hash::Merge以此为例。考虑:

use v6;
use Hash::Merge; # <-- imports all symbols marked with "is export" from Hash::Merge
my %hash1 = a1 => [1, 2, 3], b => "xxx", c => { ca => 1 }, e => 5;
my %hash2 = a1 => [1, 5, 3], b => "yyyy", c => { ca => 5, f => "a" }, d => 4;
my %res = merge-hash(%hash1, %hash2, :no-append-array);

假设我不想在使用模块时污染我的命名空间(这里Hash::Merge作为例子)。我可以在 Perl 5 中通过指定一个空参数列表来实现这一点use

use Hash::Merge ();   # <-- No symbols will be imported into the current namespace

然后我会merge-hash使用它的完全限定名称调用子例程: Hash::Merge::merge-hash.

根据这个错误报告,这似乎在 Perl 6 中是不可能的。这是正确的吗?

标签: raku

解决方案


要在不导入的情况下加载模块,请need改用:

need Hash::Merge;

对于有问题的模块,它没有声明它导出的东西our,不幸的是,这意味着将其称为:

Hash::Merge::merge-hash(...)

不起作用,因为它没有安装在包中。但是,仍然可以手动从导出中挖掘符号:

need Hash::Merge;
say Hash::Merge::EXPORT::DEFAULT::merge-hash({ a => 1 }, { b => 2 })

而且,为了更方便,它可以别名:

need Hash::Merge;
my constant &merge-hash = &Hash::Merge::EXPORT::DEFAULT::merge-hash;
say merge-hash({ a => 1 }, { b => 2 });

沿线有一个推测的语法use Hash::Merge :MY<&merge-hash>,它在当前的 Perl 6 版本中没有实现,但可能与constant这里显示的技巧具有相同的语义。


推荐阅读