Nil Shall Warn or Fail but Not Both

楽土

正如之前宣布的那样,我去写了一个模块,让 Nil.list 表现得更好一些。基本上有两种方式可以把 Nil 变成一个 list。一种是像 Nil.Str 一样发出警告,另一种是大声结束程序。然而同时做这两种方式是不合理的。

有几种方法可以做到这一点。一种是给 Nil 增加一个 list 方法,让这个方法检查一个动态变量来选择想要的行为。这样做会很慢,而且如果在循环中调用 Nil.list,可能会造成伤害。另一种方法是使用一个自定义的 sub EXPORT 和一个给定的开关。

# lib/NoNilList/Warning.pm6
use NoNilList 'Warning';
# lib/NoNilList/Fatal.pm6
use NoNilList 'Fatal';
# lib/NoNilList.pm6

sub EXPORT($_?) {
    given $_ {
        when 'Warning' {
             # augment Nil with a warning .list
        }
        when 'Fatal' {
             # augment Nil with a failing .list
        }
        default {
            die 'Please use NoNilList::Warning or NoNilList::Fatal.';
        }
    }

    %() # Rakudo complains without this
}

现在 use NoNilList; 会产生一个编译时的错误,并提示如何避免它。

我把增强的部分省略了,因为它不起作用。我以为我又踩到了 #2779,但被纠正了,这实际上是一个不同的错误。Jnthn++ 修正了那个新 bug 的一部分 (是的,Perl 6 bug 是如此的先进,它们有多个部分。) 并建议使用 MOP 来代替。这就是 #2897 的结果。棘手的是,我必须将 Nilaugment 延迟到 $_ 的检查之后,因为 augment 是一个声明符,因此在编译时执行–在一个模块中,可能在程序开始运行前几个月才执行。EVAL 字符串中的 augment 和 MOP 路径都会通向那里。我想用这个模块作为我在 6PAN 上的首次亮相。那就只能等下次了。

如果你发现了一个 bug,请把它归档。它肯定会带来令人感兴趣的发现

by glfdex

comments powered by Disqus