主题就是主题

The Topic Is the Topic

我在上一篇文章中感叹,我们缺少初学者的资料。我给出的理由是,写这种指南很难。这就有一个问题,为什么会那么难。在堵住文档漏洞时,我发现很多地方都出现了很多语言的特点。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

comments powered by Disqus