Monkey See No Nil

楽土

for 循环中,Nil 变成了一个 List,其中有一个元素恰好是 Any。这让我很不爽,所以我去找原因。结果发现罪魁祸首就是 Nil 的定义是 Cool。为了能够把任何一个值变成一个 ListCool 实现了方法 list()。它接受一个单一的值,并将这个值变成一个有这一个值的 ListNil 表示不存在一个值,把它变成一个值是没有意义的。幸运的是我们可以改变这一点。

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 通过立即死机来实现 pushappendunshiftprepend。向 nothing 添加更多的东西是致命的,但是先把 nothing 变成一个含糊不清的未定义的东西,然后再允许向它添加更多的东西,充其量是不一致的。这让我相信,Nil.list 今天的规范只是一个疏忽。

至少我现在可以写一个简单的模块来保护我的代码不受 Nil 的影响。

by gfldex.

comments powered by Disqus