2016-08-15 14 views
9

Mam zdefiniowany nowy typ Tuple następująco:Dlaczego Perl6 nie sprawdza długości tablicy po dodaniu?

subset Tuple of Array where { .elems == 2 && .[0] < .[1] }; 
my Tuple $t = [1, 2]; 
say $t; # [1 2] So far, so good. 

Nie mogę zainicjować go z krótszym lub dłuższym tablicy lub z [2, 1], jak oczekiwano. Ale mogę dodać:

$t.append(3); 
say $t; # [1 2 3] Ouch! 

Jak to możliwe?

Odpowiedz

4

Ograniczenie typu jest przypisane do kontenera skalarnego, ale obiekt, który zawiera, jest po prostu zwykłą starą tablicą - a metoda tablicowa append nie jest świadoma, że ​​ma wywołać kontrolę typu.

Jeśli chcesz ponownie aktywować czek ponownie, możesz zmienić przypisanie, na przykład $t = $t.

6

my Tuple $t tworzy zmienną taką, że każde (ponowne) przyporządkowanie lub (ponowne) powiązanie z nią musi (ponownie) przejść test typu typu: Tuple.

= [1, 2] przydziela odniesienie do obiektu Array. Sprawdzanie typu Tuple jest stosowane (i przechodzi).

$t.append(3) modyfikuje zawartość obiektu Array odbyło się w $t ale nie przypisanie lub ponownie powiązać $t więc nie sprawdzić typ.

Składnia metody Mutating - wywołanie metody - $t.=append(3) zamiast $t.append(3) - uruchomi sprawdzanie typu na $t.

Istnieje specyficzna składnia dla tablicy sprawdzanej przez granice (my @array[2] itd.), Ale domyślam się, że nie o to pytasz.

1

Jeśli naprawdę chcesz zmienić wersję Array, możesz po prostu utworzyć klasę, która dziedziczy po niej i nadpisuje metody, które chcesz inaczej zachowywać. (Istnieją prawdopodobnie znacznie bardziej elegancki sposób, aby to zrobić, ale to działa):

class Tuple is Array { 
    method append (*@val) { 
     fail '"append" is disabled for Tuples' 
    } 
} 

my $t = Tuple.new(1,2); 

say $t; 

$t.append(3); 

Wtedy to będzie działać jak można się spodziewać:

[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 

Naprzemiennie dostać coś podobnego można użyć zwymiarowana tablica as mentioned by raiph. Lub, jeśli po prostu chcesz czegoś niezmiennego, który jest podobny do tablicy, możesz użyć List.

Powiązane problemy