How to avoid importing default symbols when using a module?

Håk*_*and 8 perl6 raku

I am going to use Hash::Merge as an example. Consider:

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);
Run Code Online (Sandbox Code Playgroud)

Suppose I do not want to pollute my name space when using a module (here Hash::Merge is used as an example). I could achive this in Perl 5 by specifying an empty argument list to use:

use Hash::Merge ();   # <-- No symbols will be imported into the current namespace
Run Code Online (Sandbox Code Playgroud)

Then I would call the sub routine merge-hash using its fully qualified name: Hash::Merge::merge-hash.

According to this bug report it seems like this is not possible in Perl 6. Is this correct?

Jon*_*ton 9

要加载模块而不导入,请need改用:

need Hash::Merge;
Run Code Online (Sandbox Code Playgroud)

对于所涉及的模块,它不会声明使用其导出的内容our,不幸的是,这意味着将其调用为:

Hash::Merge::merge-hash(...)
Run Code Online (Sandbox Code Playgroud)

由于未安装在软件包中,因此无法使用。但是,仍然可以手动从导出中挖掘符号:

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

并且,为方便起见,可以使用别名:

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

在的基础上有一种推测的语法use Hash::Merge :MY<&merge-hash>,在当前的Perl 6版本中未实现,但是可能具有与constant此处显示的技巧相同的语义。


Bra*_*ert 8

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

{ use Hash::Merge }
Run Code Online (Sandbox Code Playgroud)

由于{}定义了作用域,因此无法逃脱。

您可以将其放置在一个do块中,以使某些东西可以逃脱。

do { use Hash::Merge }
Run Code Online (Sandbox Code Playgroud)

然后,您可以做的就是将其保存下来,以便将您关心的值存储在正确的位置。

my &merge-hash = do { use Hash::Merge; &merge-hash }
Run Code Online (Sandbox Code Playgroud)
my (&merge-hash,&merge-hashes) = do { use Hash::Merge; (&merge-hash, &merge-hashes) }
Run Code Online (Sandbox Code Playgroud)

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

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

my %c;
{
  use Hash::Merge;
  %c := merge-hash %a, %b
}
Run Code Online (Sandbox Code Playgroud)

要么

my %c := do {
  use Hash::Merge;
  merge-hash %a, %b
}
Run Code Online (Sandbox Code Playgroud)

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