在 for
循环中,Nil
变成了一个 List
,其中有一个元素恰好是 Any
。这让我很不爽,所以我去找原因。结果发现罪魁祸首就是 Nil
的定义是 Cool
。为了能够把任何一个值变成一个 List
,Cool
实现了方法 list()
。它接受一个单一的值,并将这个值变成一个有这一个值的 List
。Nil
表示不存在一个值,把它变成一个值是没有意义的。幸运的是我们可以改变这一点。
use MONKEY-TYPING;
augment class Nil {
method list() {
note 'Trying to turn Nil into a list.';
note Backtrace.new.list.tail.Str;
Empty
}
}
Nil.HOW.compose(Nil);
sub niler() { Nil }
for niler() { say 'oi‽' }
我们不能只是警告,因为那会在堆栈跟踪中显示错误的点。所以我们注意到(也会转到 $*ERR
),并从 Backtrace 中提取最后一个值。
有趣的是 Failure 在 .list
和 .iterator
中都会抛出。Nil
通过立即死机来实现 push
、append
、unshift
和 prepend
。向 nothing
添加更多的东西是致命的,但是先把 nothing 变成一个含糊不清的未定义的东西,然后再允许向它添加更多的东西,充其量是不一致的。这让我相信,Nil.list
今天的规范只是一个疏忽。
至少我现在可以写一个简单的模块来保护我的代码不受 Nil
的影响。
by gfldex.