We can use the total
method to know the sum of all the weights in a Bag
.
> my $b = (1,2,1).Bag
Bag(1(2), 2)
> $b.total
3
But if we use the %
sigil instead of $
for our Bag
, we get an error message.
> my %b = (1,2,1).Bag
{1 => 2, 2 => 1}
> %b.total
No such method 'total' for invocant of type 'Hash'. Did you mean 'cotan'?
in block <unit> at <unknown file> line 1
If %b
is explicitly converted to Bag
before total
, it works:
> %b.Bag.total
3
The question: I used to think that with Set
, Bag
, SetHash
etc., using the %
sigil is preferable. Am I wrong?
my %b := (1,2,1).Bag;
say %b.total
Binding (with :=
) binds the right hand side directly to the left hand side. In this case a value that does the Associative
role gets bound to %b
.
Bag
Assigning (with =
) assigns (copies) values from the right hand side into the container on the left hand side.
You can assign after first binding to a Bag
as follows.
Immediately prior to an assignment a my
declarator will bind a suitable container to the declared variable. By default it will be a Hash
container if the variable has a %
sigil.
But you can specify a variable is
bound to some other type of container that's compatible with its sigil:
my %b is Bag = 1,2,1;
say %b.total
With this incantation you need to use =
because, by the time that operator is encountered %b
has already been bound to a Bag
and now you need to assign (copy) into the Bag
.
This way you get the simplicity of just providing a list of values (no explicit keys or Bag
coercer/constructor necessary) because =
is interpreted according to the needs of the container on its left, and a Bag
choses to interpret the RHS of =
as a list of keys whose occurrence count is what matters to it.
In Perl 6, assignment to a container can be coercive, that is, it coerces the value to that of the container. See this:
my $b = (1,2,1).Bag;
say $b.^name; # Bag
my %haШ = (1,2,1).Bag;
say %haШ.^name; # Hash
Binding, on the other hand, binds the type of the container to the contained thing.
So, the answer: you can still use the sigil, but as @raiph said above, use binding so that the Bag or BagHash is not coerced into a simple Hash.
my %real-haШ := (1,2,1).Bag;
say %real-haШ.^name; # Bag
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