我在上一篇文章中感叹,我们缺少初学者的资料。我给出的理由是,写这种指南很难。这就有一个问题,为什么会那么难。在堵住文档的漏洞时,我发现很多地方都出现了很多语言的特点。Raku 和自己是交织在一起的。对于初学者来说,你会希望从一些简单的东西开始,然后在此基础上建立,直到你达到最大的复杂性。有什么能比谦逊的 if
语句更简单呢?事实上,有很多。原因是主题。这将是这篇文章的主题。
正如大家所料,Topic 在 Raku 中出现在很多地方。不熟悉的人甚至会认为它像魔术一样出现。所以,让我们给 Callable 添加一个神奇的变量。
my $magic = 42;
sub s( $hmm? is raw = OUTER::<$magic>) { $magic = $magic == 42 ?? 'answer' !! 'nope' }
s;
say $magic;
# OUTPUT: answer
这正是 Block 交出 Topic 的方法。
my &block = {;}
say &block.signature;
# OUTPUT: (;; $_? is raw = OUTER::<$_>)
Raku 中的很多语言元素都是默认设置主题的。If 只有在我们要求的时候才会这样做。
if 42 { $_.say }
if 42 -> $_ { $_.say }
# OUTPUT: (Any)
# 42
编译器如何知道其中的区别?
my &pointy = -> $_ {;};
say &pointy.signature;
# OUTPUT: ($_)
尖块中的显式参数是不可选的。我们可以用 [arity](https://docs.raku.org/type/Signature#method_arity)
和 [count](https://docs.raku.org/type/Signature#method_count)
来区分它们。
say [&block.signature.arity, &pointy.signature.arity];
say [&block.signature.count, &pointy.signature.count];
# OUTPUT: [0 1]
# [1 1]
还有一种方法是如何改变块的 arity
。
&block = { $^a.say };
say [&block.signature, &block.signature.arity];
if 42 { say $^a }
# OUTPUT: [($a) 1]
# 42
还是不相信编译器不会作弊?
if 42 { say $^_ }
# OUTPUT:
# Redeclaration of symbol '$^_' as a placeholder parameter
# at /home/dex/projects/blog/topic-is-topic.raku:69
# ------> if 42 { say $^_⏏ }
这并不意味着编译器不会作弊。毕竟它是编译器。但在 Raku 中,这是其中的一个地方,在这里,事情就会发生。通过使用一种叫做 Signature 的语言来描述 Callables 的参数和对作用域的访问,就不需要用魔法来实现魔法变量了。
这篇博文是由文档中的一个漏洞引发的。在写这篇文章的时候,我又发现了一个漏洞。我们忘记了提到空块的字面量是 {;}
。我们需要做的就是通过 Roast 找到所有的漏洞,看看那里提到的东西是否也在文档中。遗憾的是,在接下来的900多天里,我还有其他事情要做。
不过抱怨够了。让我们用一个积极的结论来结束。Raku 可能看起来像魔法。其实不是。它实际上非常聪明。
by gfldex