这几乎是在北极附近的精灵小学冬季学期结束之时。对于精灵而言,敏锐的人物头脑非常重要,而小精灵的数学老师 Hopper 女士希望确保他们在任期的倒数第二天保持他们的算术技能。(学期的最后一天保留用于观看电影和玩耍 - 很嗨皮)。
小精灵刚刚学会了他们的时间表(乘法表),最多12个,但他们并不像他们所想的那样擅长,其中一些人在圣诞节前将在玩具工作坊帮忙,那时候他们可能需要快速告诉大精灵有多少特定类型的玩具。
幸运的是,Elf Hopper 是一个非常聪明的精灵,拥有出色的数学和编码能力 - 自己。所以她起了一个快速的控制台应用程序来运行小精灵的学校颁发的 Perlix 6.0 boxen。
该程序允许小精灵通过运行它们在2至12次表中测试自己,或者如果它们提供单个数字参数,他们可以尝试任何他们喜欢的乘法表。
#!/usr/bin/env raku
use v6;
my $fixednum;
my %score;
my @exits = <exit quit>;
$fixednum = @*ARGS[0] || 0;
put "Type the answer, or quit or exit to end the test.";
loop {
my $coefficient = (2..12).pick;
my $number = $fixednum || (2..12).pick;
my $answer = prompt ( "$coefficient × $number = " );
my $rightanswer = $coefficient × $number;
last if $answer.lc ~~ any @exits;
if $answer == $rightanswer {
put "Correct!";
%score<correct>++;
} else {
put "Sorry, that wasn't right! The answer is $rightanswer";
}
%score<total>++;
}
if %score<total>:exists {
my $pc = 100 * %score<correct> / %score<total>;
put "You scored %score<correct> out of %score<total>, i.e. ", sprintf "%2.2f%%.", $pc;
}
Elf Hopper 向其它小精灵解释代码如下。
“可爱的小精灵们!这是关于程序如何工作的一些背景知识。
我在顶部附近添加了 use v6;
,以便代码也可以在 Perl 5下 运行,它将自动使用 Raku 仿真器。
您将看到程序在特殊的 @*ARGS
数组的命令行上运行时选择一个可选参数。这是 Perl 5 的 @ARGV
数组的 Raku 等价物。
在 Raku 中,数组,数组元素和数组切片总是使用 @
sigil,与 Perl 5 不同,其中各个数组元素使用 $
sigil。同样,哈希和哈希元素现在总是带有 %
sigil,无论是整个哈希,它的切片还是单个元素都在使用。
那里还有另一个符号,星号 ‘twigil’,*
。这表明 @*ARGS
是一个动态特殊变量。
prompt
和 loop
关键字是 Raku 中的新功能,两者都是令人钦佩的名字!
prompt
只返回用户输入的值,在本例中为变量。loop
是 Raku 的新块控制关键字之一。像这样的简单循环块只是创建了一个无限循环,可以由程序员以显式的方式结束,例如在满足条件时使用last
关键字;或者例如由用户手动终止程序。- 或者,循环可以采用三个参数,并且表现得像传统的C风格
for
循环。 (在 Raku 中,小精灵,for
只用于迭代列表或其他容器。)
在循环内部,小精灵,你可以看到范围对象。一切都是 Raku 中的一个对象,所以我可以在范围上调用 pick
方法来返回一个随机数。(好吧,无论如何,这是一个非加密安全的伪随机数!)
any
关键字将 @exits
数组转换为 Raku 中许多新的有用数据结构之一:一个 Junction。这使得使用 smartmatch 运算符 ~~
直截了当地找到一个数组元素。last
关键字退出循环,如 Perl 5 中所示。
Junction 是一种新类型的容器或列表,允许进行许多最有用的比较,例如 any
,all
,one
或 none
,我们在 Perl 5 中使用 grep
或 List::Util
等模块进行比较,但它使它们成为可能键入更容易,并允许它们同时执行!这样做的一个副作用是 junction 是无序的:但它们主要是为了产生单个真值或假值,所以通常都可以。如果你想快速想要根据一些特定值的简短列表检查一个值,那么 junction 就很棒。但是如果需要的话,它们还能够让你匹配更大的值集。
在最后一个代码段落的顶部,您将看到 :exists
应用于 %score<total>
哈希键。:exists
是一个 Raku 副词!副词通常会修改方法的工作方式。:exists
是下标副词。它是一个副词,因为它改变了读取哈希键时发生的事情:不是返回值,而是查明值是否存在。这通常是使用 Perl 5 类中关注的那些熟悉的已定义方法的更好的替代方法。
当然,exists
测试就是为了确保在用户第一次退出程序时不会出现错误。
为什么我使用锯齿形符号来引用哈希键?好吧,花括号 {}
是散列键的标准下标运算符,如 Perl 5. 但是,大多数情况下你可能想要使用尖括号/锯齿形符号,因为它们提供单字键的自动引用。用于在 Perl 5 中执行此操作的简单{}
括号,但在 Raku 中不再执行此操作。需要引起括号内的字符串。
在 Raku 中,放置了用于向终端输出文本的标准命令。这将输出以下列表项,然后是换行符。say
和 print
仍然可用; say
和 put
这两个都打印到标准输出并添加换行符; print
不会追加换行符。
如果你使用这个程序以及知道它是如何工作的,小精灵,你将有选择和知识,是否,何时以及如何在你自己的头脑中执行乘法,以及什么时候最好让 Raku -有动力的电脑做它。您的圣诞节作业是让您自己熟悉https://docs.raku.org 上的 Raku 文档。“
小精灵开始使用乘法测试程序,试图超越对方以获得最高的完美分数。他们发现它如此令人上瘾,以至于比赛甚至会加时到在学校的最后一天,当时他们应该正在观看’精灵'!