Reputation: 242103
I've defined a new type Tuple
as follows:
subset Tuple of Array where { .elems == 2 && .[0] < .[1] };
my Tuple $t = [1, 2];
say $t; # [1 2] So far, so good.
I can't initialize it with shorter or longer array or with [2, 1]
, as expected. But, I can append to it:
$t.append(3);
say $t; # [1 2 3] Ouch!
How's that possible?
Upvotes: 9
Views: 156
Reputation: 11168
If you really want an altered version of an Array
, you can simply create a class that inherits from it and overrides the methods that you want to behave differently. (There are probably much more elegant ways to do this, but this does work):
class Tuple is Array {
method append ( *@val ) {
fail '"append" is disabled for Tuples'
}
}
my $t = Tuple.new(1,2);
say $t;
$t.append(3);
Then it will work like you expect:
[1 2]
"append" is disabled for Tuples
in method append at example.p6 line 2
in block <unit> at example.p6 line 11
Actually thrown at:
in block <unit> at example.p6 line 11
Alternately, to get something similar you could use a dimensioned array as mentioned by raiph. Or, if you simply want something immutable that is similar to an array, you can then use a List
.
Upvotes: 1
Reputation: 32489
my Tuple $t
creates a $t
variable such that any (re)assignment or (re)binding to it must (re)pass the Tuple
type check.
= [1, 2]
assigns a reference to an Array
object. The Tuple
type check is applied (and passes).
$t.append(3)
modifies the contents of the Array
object held in $t
but does not reassign or rebind $t
so there's no type check.
Mutating-method-call syntax -- $t.=append(3)
instead of $t.append(3)
-- will trigger the type check on $t
.
There is specific syntax for a bounds-checked array (my @array[2]
etc.) but I'm guessing that's not the point of your question.
Upvotes: 6
Reputation: 169713
The type constraint is bound to the scalar container, but the object it contains is just a plain old array - and an array's append
method is unaware you want it to trigger a type check.
If you want to explicitly trigger the check again, you could do a reassignment like $t = $t
.
Upvotes: 4