用Buf测试模块'isa-ok'

Cur*_*mes 6 testing perl6

使用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;
Run Code Online (Sandbox Code Playgroud)

这是输出:

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'

Run Code Online (Sandbox Code Playgroud)

isa-ok真正如何运作?这与公正~~有何不同?与Bufvs 测试对象有什么区别'Buf'?为什么不Buf认为是isaa BufBlob?(虽然它isa是一个,'Buf'但仍然不是'Blob'

通常,是否isa-ok了解角色或必须does-ok使用角色?

rai*_*iph 6

See isa-ok不适用于参数化类型。(我认为该问题的标题具有误导性,因为它实际上是关于类与未参数化与未参数化类型的角色的对比。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
}
Run Code Online (Sandbox Code Playgroud)

仅当类型为类时,第一个multi才有效。在P6字“ISA”具有技术意义的是A isa B当且仅当这两个ABA正在或继承而来,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'
Run Code Online (Sandbox Code Playgroud)

字符串版本isa-ok仅在您传递类型名称的字符串版本时适用。无论是好是坏,它都允许您采用更随意的方式来考虑类型,并且会接受精确匹配。

~~是“智能匹配”。由右边的类型决定是否将左边的东西视为匹配项。

通常,是否isa-ok了解角色或必须does-ok使用角色?

不,不是。您应该使用does-ok