使用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
,但还不是'Buf'
吗?通常,
'Blob'
是否了解角色,还是必须将isa-ok
用于角色? 最佳答案
参见 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 B
和A
都是类,而B
是A
或从B
继承,则isa
。(更具体地说,执行
Perl6::Metamodel::MROBasedTypeChecking
的类的role
解析为相应Buf
中的方法,该方法根据经过类的方法解析顺序检查是否匹配。)像
Buf.new
这样的类型是角色。 (可以通过Buf
轻松地将角色“刺入”相应的匿名类/实例,但这并不能阻止Array
本身就是一个角色。)像
Array
这样的类型可以工作,因为isa-ok
是一个类。所以:
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'
字符串类型的
~~
仅在传递类型名称的字符串版本时适用。不管是好是坏,它都允许使用更随意的方式来考虑类型,并且会接受精确的匹配。does-ok
是“智能匹配”。由右边的类型决定是否将左边的东西视为匹配项。不,不是。您应该使用ojit_code。
关于testing - 用Bu测试 'isa-ok'模块,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55196514/