Guifa 对 $xml.elements
在没有子节点的情况下返回一个带有一个未定义元素的列表感到不满。这让我得出了一个结论:Nil
只有 Empty
的一半。
让我们考虑一下这段代码。
sub nilish() { Nil };
for nilish() { say 'oi‽' }
my $nil := nilish();
for $nil { say 'still oi‽' }
sub no-return() { }
for no-return() { say 'even more oi‽' }
sub return-a-list( --> List:D ) { Nil }
for return-a-list() { say 'Should this happen?' }
# OUTPUT:
# oi‽
# still oi‽
# even more oi‽
# Should this happen?
我们正在迭代名为 Nil
的特殊容器-重置值,因为没有容器可以重置。因为 for
绑定了它的参数,所以它绑定了 Nil
。一个类型对象,即使是像 Nil
这样非常特殊的类型对象,也是一个单项,它被 for
当作一个只有一个元素的列表。
我们可以通过将不合理的值变成空列表的多子来解决这个问题。
multi sub undefined-to-empty(Nil) { Empty }
multi sub undefined-to-empty(@a where all @a.map(!*.defined)) { Empty }
multi sub undefined-to-empty(\item) { item }
for undefined-to-empty(Nil) { say 'nothing happens' }
for undefined-to-empty((Any,)) { say 'nothing happens' }
通过添加一个候选人来检查列表中是否只有未定义的值,我们也可以解决 guifa 的问题。
这只是一个小插曲。真正的解决方案是停止在本地绑定中把 null
变成 Nil
。如果你写了一个 sub,必须返回一个列表,但不能失败或返回空,如果没有什么可返回。为了帮助将来避免这个错误,我提交了 #2721。
如果它看起来是空的,或者听起来是 emtpy 的,或者尝起来是 emtpy 的,那就把它做成 Empty
!
by gfldex.