如何测试Perl 6类中是否定义了方法?

时间:2018-03-12 22:45:17

标签: testing perl6

我经常想测试我在特定类中定义了一个方法。这已经解决了许多问题,我已经重命名了一个方法或者重新安排了架构中的东西。

我知道我可以使用webdriver-manager start/update,但这对我来说仍然感觉很奇怪,因为我最终会遇到一个案例,它以不同的顺序返回事物(暂时忽略签名) 。这就是我想出的:

.^lookup

在这个简单的案例中,我做了我想做的事情,到目前为止我还没有让它失败:

use Test;

class Foo is Str {}
class Bar is Str { method Str { 'Hello' } }

can-ok Str, 'Str';
can-ok Foo, 'Str';
can-ok Bar, 'Str';

is Foo.^lookup( 'Str' ).package.^name, 'Foo', 'Foo defines Str';
is Bar.^lookup( 'Str' ).package.^name, 'Bar', 'Bar defines Str';

done-testing;

1 个答案:

答案 0 :(得分:7)

您不应该按名称比较类型。

my \Foo = anon class Foo {}
my \Bar = anon class Foo {}

say Foo.^name eq  Bar.^name; # True
say Foo       eqv Bar;       # False

实际上is检查对象标识,如果你给它一个类型对象作为第二个参数。

is Bar.^lookup( 'Str' ).package, Bar, 'Bar defines Str'

您可以随时添加子程序以增加清晰度。

sub defines-method (
  Mu:U $class,
  Str:D $method,
  Str:D $desc = "$class.^name() defines $method"
) {
  is $class.^lookup( $method ).?package, $class, $desc
}

defines-method Foo, 'Str';

您可以将其别名为运算符

sub &infix:<defines-method> = &defines-method;

Bar defines-method 'Str';

(请注意,如果.?package没有返回任何内容,我会使用.^lookup。)

.^lookup为您提供将被调用的 Method 对象;所以我不知道为什么你在谈论它,当只有一个值返回时,它会以不同的顺序给你。如果有多种方法,则返回proto方法(可能隐式创建) 如果您想要单独的多种方法,可以在其上调用.candidates (还有.^find_method,而且我不记得其中的差异了。

我相信您正在考虑.can,如果您使用.*Str.+Str,它会按照调用顺序为您提供Method对象,这与方法解析相同订购。这意味着只有在更改继承树时才会更改。

> class Bar is Str { method Str { 'Hello' } }

> quietly .perl.say for Bar.+Str;
"Hello"
""
""

> .perl.say for Bar.new.+Str
"Hello"
""
"Bar<80122504>"

> quietly .(Bar).perl.say for Bar.can('Str')
"Hello"
""
""

> .(Bar.new).perl.say for Bar.can('Str')
"Hello"
""
"Bar<86744200>"