How to avoid importing default symbols when using a module?

To load a module without importing, use need instead:

need Hash::Merge;

In the case of the module in question, it does not declare the things it exports with our, which unfortunately means that calling it as:

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

Will not work, since it's not installed in the package. However, it is still possible to dig the symbol out of the exports manually:

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

And, for more convenience, it can be aliased:

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

There is a speculated syntax along the lines of use Hash::Merge :MY<&merge-hash>, which is not implemented in current Perl 6 versions, but would probably have the same semantics as the constant trick shown here.


A simple way to deal with this is to just put the use of the module in a block.

{ use Hash::Merge }

Since the {} defines a scope, nothing escapes it.

You can get it so that something can escape by placing it in a do block.

do { use Hash::Merge }

What you can do then is have it so that the values you care about get stored in the correct places.

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

Another option is to just place it in as small a scope as possible.

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

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

or

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

(The binding operator := was just used because the result of merge-hash is already a hash.)

Tags:

Raku