即使您显式调用.sink
了该返回值,Failure
也不会崩溃:
sub might-sink {
return [1,2,Failure.new("boo!"),"still here"];
}
might-sink.sink;
say "Did not explode";
# OUTPUT: Did not explode
代码中的爆炸发生在调用期间的再现.gist
期间say
,它会遍历您的前 100 个元素Array
并调用.gist
它们。当它在Failure
元素上这样做时,它会引爆它。
您将下沉列表对象本身和下沉它包含的单个值混为一谈。您正确提到List.sink
的是无操作,但Seq.sink
会消耗自己¹,但它也不会爆炸,因为只是Seq
沉没,而不是其单个元素:(+"a", 42).Seq.sink
如果你想强制潜在的Failure
爆炸,你可以:
1 use fatal
:。Failures
这将导致编译器致命失败,导致它们在许多传递的地方爆炸。这是一个词法编译指示,它也自动在try {}
块中启用。
use fatal;
sub might-sink {
return [1,2,Failure.new("boo!"),"still here"];
}
might-sink;
# OUTPUT:
# boo!
# in block <unit> at
2: Hyper over.self
方法调用。它由Mu
(所以被所有对象继承)提供并且简单地返回self
,所以它是一个无操作(除了做decont)。但是,由于大多数调用武装的方法都会导致它们Failure
引爆,因此调用.self
它们会导致它们爆炸。
sub might-sink {
return [1,2,Failure.new("boo!"),"still here"];
}
might-sink».self;
# OUTPUT:
# boo!
# in block <unit> at
如何使用 Perl 6 调试器或模块调试这些函数?
不要自己使用调试器,但perl6-debug-m
应该在您的 Rakudo 安装中预装。它需要您安装Debugger::UI::CommandLine
模块。你只是使用它而不是perl6
运行你的程序,它应该在命令行上提供一些关于它做什么的说明。还有一篇关于它的博客文章和一个视频(需要 Flash 才能播放)。
还有一个最近发布的 alpha 质量App::MoarVM::Debug
,让您甚至可以远程调试程序。它的美妙之处在于它可以让您在程序运行时转储对象内容并导航它们,因此如果您可以忍受它的界面,它会很方便。
就个人而言,我只使用dd
例程在战略点中转储内容并查看它是否包含我期望它包含的内容来进行调试。
如何确定 List.sink 是否实际被调用,或者一般来说,当对象在接收器上下文中发现自己时是否调用了接收器?
does
您可以使用或操作符来混合角色but
,该操作符提供了sink
一种可以执行您可以观看的操作的方法。比如打印一些东西:
sub foo {
return [<a b c>] does role {
method sink { say "sink called" }
}
}
foo
# OUTPUT: sink called
更高级的方法是转储优化后的QAST 树并查看它是否包含您期望的调用。CoreHackers::Q
模块使转储的 QAST 树更易于可视化。
PS:关于隐含下沉的话题,值得注意的是R#1571列举了几个错误,并建议对处理下沉的内部系统进行完全重新设计。
¹ - 更准确地说,Seq.sink
调用.sink-all
its Iterator
,默认情况下它只是简单地使用这些值,但自定义迭代器也可以将该方法覆盖为无操作。