使用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
是否理解角色或必须使用does-ok
?
见isa-ok
does not work with parametrized types。 (我认为问题标题是误导性的,因为aiui它真的是关于类和角色没有参数化和非参数化类型。毕竟可以写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
}
第一个多只有在类型是类时才有效。在P6中,“isa”一词具有技术含义,即A isa B
,如果A
和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
是否理解角色或必须使用does-ok
?
不,不。你应该使用qazxswpoi。