使用模块时如何避免导入默认符号?

时间:2019-03-31 11:50:25

标签: perl6

我将以https://www.npmjs.com/package/react-native-get-music-files为例。考虑:

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-hashHash::Merge::merge-hash

根据Hash::Merge,在Perl 6中似乎无法实现。这是正确的吗?

2 个答案:

答案 0 :(得分:9)

要加载模块而不导入,请改用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技巧具有相同的语义。

答案 1 :(得分:8)

一种简单的处理方法是将模块的使用放在一个块中。

{ use Hash::Merge }

由于{}定义了范围,因此没有任何内容可以逃脱。

您可以通过将其放置在do块中来使它逃脱。

do { use Hash::Merge }

那么您所能做的就是拥有它,以便您关心的值存储在正确的位置。

my &merge-hash = do { use Hash::Merge; &merge-hash }
my (&merge-hash,&merge-hashes) = do { use Hash::Merge; (&merge-hash, &merge-hashes) }

另一种选择是将其放置在尽可能小的范围内。

my %a = a => 1;
my %b = b => 2;

my %c;
{
  use Hash::Merge;
  %c := merge-hash %a, %b
}

my %c := do {
  use Hash::Merge;
  merge-hash %a, %b
}

(由于:=的结果已经是哈希值,因此仅使用了绑定运算符merge-hash。)