Тестовый модуль 'isa-ok' с Buf - PullRequest
6 голосов
/ 16 марта 2019

Использование модуля Perl6 Test для проверки типа объекта с помощью Buf:

use Test;
isa-ok Buf.new, Buf;
isa-ok Buf.new, Blob;
isa-ok Buf.new, 'Buf';
isa-ok Buf.new, 'Blob';
ok Buf.new ~~ Buf;
ok Buf.new ~~ Blob;
does-ok Buf.new, Buf;
does-ok Buf.new, Blob;

Вот вывод:

not ok 1 - The object is-a 'Buf'
# Failed test 'The object is-a 'Buf''
# at buftest line 3
# Actual type: Buf
not ok 2 - The object is-a 'Blob'
# Failed test 'The object is-a 'Blob''
# at buftest line 5
# Actual type: Buf
ok 3 - The object is-a '"Buf"'
not ok 4 - The object is-a '"Blob"'
# Failed test 'The object is-a '"Blob"''
# at buftest line 9
# Actual type: Buf
ok 5 - 
ok 6 - 
ok 7 - The object does role 'Buf'
ok 8 - The object does role 'Blob'

Как на самом деле работает isa-ok?Чем это отличается от ~~?В чем разница между тестированием объекта по Buf против 'Buf'?Почему Buf не считается isa Buf или Blob?(хотя это isa a 'Buf', но все еще не 'Blob'?

В общем, isa-ok понимает роли или должен does-ok использоваться для них?

1 Ответ

6 голосов
/ 16 марта 2019

См. isa-ok не работает с параметризованными типами .(Я думаю, что название проблемы вводит в заблуждение, потому что aiui на самом деле о классах против ролей, не параметризованных против непараметризованных типов. В конце концов, можно написать Array[Int], и это, возможно, параметризованный тип.)

Я нашел это поиск в репо Rakudo Github 'isa-ok' и нажатие на Issues.

Mu.pm6 определяет isa:

proto method isa(|) {*}

multi method isa(Mu \SELF: Mu $type --> Bool:D) {
    nqp::hllbool(SELF.^isa($type.WHAT))
}

multi method isa(Mu \SELF: Str:D $name --> Bool:D) {
    return True if .^name eq $name for SELF.^mro;
    False
}

Первый мульти работает только если тип является классом.В P6 слово «isa» имеет техническое значение, которое A isa B если A и B являются классами и A is, или наследует от B.

(Более конкретно, isa класса, который делает Perl6::Metamodel::MROBasedTypeChecking, разрешается в метод в соответствующем role, который проверяет совпадение на основе прохождения порядка разрешения метода класса.)

Тип типа Buf - это роль.(Роли могут быть легко «вставлены» в соответствующие анонимные классы / экземпляры, например, Buf.new, но это не останавливает Buf саму роль.)

Тип, подобный Array, работаетпотому что Array является классом.

Итак:

put Array.HOW.^name; # Perl6::Metamodel::ClassHOW+{<anon>}
say Array.^mro;      # ((Array) (List) (Cool) (Any) (Mu))
isa-ok Array, List;  # ok
put Buf.HOW.^name;   # Perl6::Metamodel::ParametricRoleGroupHOW
say Buf.^mro;        # No such method 'mro' for invocant of type
                     # 'Perl6::Metamodel::ParametricRoleGroupHOW'

Строковая версия isa-ok применяется, только если вы передаете строковую версию имени типа.Хорошо это или плохо, но допускает небрежное представление о типах и принимает точное совпадение.

~~ - это «умное сопоставление».Право выбора типа справа - решить, считать ли вещь слева совпадением.

В общем, isa-ok понимает роли или должен использоваться does-ok для них?

Нет, это не так.Вы должны использовать does-ok.

...