Глядя на документацию для "===", последняя строка показывает, что оператор основан на .WHICH и что "... все типы значений должны переопределять метод WHICH." Вот почему, если вы создаете два отдельных элемента с одинаковым строковым значением , "===" возвращает Истина.
my $a = "Hello World";
my $b = join " ", "Hello", "World";
say $a === $b; # True even though different items - because same value
say $a.WHICH ; # "Str|Hello World"
say $b.WHICH ; # (same as above) which is why "===" returns True
Таким образом, вместо того, чтобы создавать свой собственный тип контейнера или использовать некоторые из ловушек для индексов, вы вместо этого можно было бы скопировать способ, которым это делают «типы значений», то есть разделить (кое-что) идею идентичности. Метод .WHICH для строк, показанных выше, просто возвращает имя типа и содержимое, соединенные с '|'. Почему бы не сделать то же самое;
class Foo {
has $.bar;
multi method WHICH(Foo:D:) { "Foo|" ~ $!bar.Str }
}
my Foo $a .= new(:bar(1));
my %h{Foo} = $a => 'A', Foo.new(:bar(2)) => 'B';
my Foo $a-prime .= new(:bar(1));
say $a eqv $a-prime; # True
say $a === $a-prime; # True
say %h{$a}; # A
say %h{$a-prime}; # A
Конечно, есть небольшие затраты - концепция идентичности для экземпляров этого класса, ну, скажем так, интересная. Какие последствия? Единственное, что сразу приходит в голову, это то, что если вы планируете использовать какой-то фреймворк для сохранения объектов, он будет сжимать разные экземпляры, которые теперь выглядят одинаково, в один (возможно).
Различные объекты с одинаковыми данными атрибутов будут неразличимы - вот почему я колебался, прежде чем опубликовать этот ответ. OTOH, это ваш класс, ваше приложение, поэтому, в зависимости от размера / важности и т. Д., Это может быть прекрасный способ сделать это.
person
Marty
schedule
05.03.2016