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);
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
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?
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With