用Buf测试模块'isa-ok'

时间:2019-03-16 12:01:01

标签: 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;

以下是输出:

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视为isaBufBlob? (虽然它是isa的{​​{1}},但还不是'Buf'

一般来说,'Blob'是了解角色还是必须使用isa-ok

1 个答案:

答案 0 :(得分:6)

请参见isa-ok does not work with parametrized types。 (我认为该问题的标题具有误导性,因为它实际上是有关类与未参数化与未参数化类型的角色。毕竟,可以写Array[Int],而且可以说是参数化类型。)

我是通过searching the Rakudo Github repo for '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
}

仅当类型为类时,第一个multi才有效。在P6中,“ isa”一词的技术含义是,A isa BA都是 classes ,而B是或A开始>继承。

(更具体地说,执行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