Raku vs. Perl5,出人意料的结果

Posted

技术标签:

【中文标题】Raku vs. Perl5,出人意料的结果【英文标题】:Raku vs. Perl5, an unexpected result 【发布时间】:2021-05-31 18:06:10 【问题描述】:

当我在Raku 中运行此脚本时,我收到带有几个换行符的A 字母。 为什么我没有按预期(和 Perl5 一样)获得连接的字符串?

编辑顺便说一句,我可以使用Perl5 编译器在commaIDE 中编译该文件,我在哪里可以将此编译器更改为Perl5 的编译器?

say "A";

my $string1  = "00aabb";
my $string2  = "02babe";

say join ("A", $string1, $string2);
print "\n";

my @strings = ($string1, $string2);

say join ("A", @strings);
print "\n";

【问题讨论】:

"我可以用 Perl5 编译器在 commaIDE 中编译该文件吗,我在哪里可以将此编译器更改为 Perl5 的编译器?" Comma 是 Raku 特定的 IDE。它不能像 Raku 一样使用 Perl 或 Python 等其他 PL。也就是说,也许可以设置一些东西,以便它可以轻松地调用外部脚本,例如其他 PL 的编译器。无论哪种方式,我建议您将此方面作为一个新的单独 SO 问题提出,以引起适当的关注。 逗号也可作为任何 IntelliJ JetBrains IDE 版本的插件使用...还有一个 perl 插件plugins.jetbrains.com/plugin/7796-perl 【参考方案1】:

我建议的解决方案是去掉括号:

say "A";

my $string1  = "00aabb";
my $string2  = "02babe";

say join "A", $string1, $string2;     # Pass THREE arguments to `join`, not ONE
print "\n";

my @strings = $string1, $string2;

say join "A", @strings;
print "\n";

(第二次调用join 中的@strings 中的元素被展平,因此与第一次调用join 的方式相同。)

以上代码显示:

A
00aabbA02babe

00aabbA02babe

当我在 Raku 中运行此脚本时,我收到带有几个换行符的 A 字母。

您的代码调用 join 时使用 ONE 参数(即连接符)和要连接的零字符串。所以join 调用会生成空字符串。因此你得到空行。

为什么我没有得到连接的字符串

代码中的两个say join... 语句只打印一个换行符,因为它们就像下面的第三和第四行say

say join(  " \o/ ", "one?", "two?" ); # one? \o/ two?␤

say join   " \o/ ", "one?", "two?"  ; # one? \o/ two?␤

say join ( " \o/ ", "one?", "two?" ); # ␤

say join(  " \o/  one? two?"       ); # ␤

上面的第一行和第二行将三个字符串传递给join。第三个传递了一个 single List,然后它被强制变成一个 single 字符串(List 的元素使用单个空格字符连接),即与第四行相同的结果。


my @strings = ($string1, $string2); 咒语恰好按您的预期工作,因为对= 左侧的“复数”变量的赋值将在右侧迭代值或值列表。

但在 Raku 中,避免冗余代码是一个好习惯,在这种情况下,只有在您确实必须使用括号来表达与没有它们的代码不同的东西时才使用括号。这是 Raku 中使代码高信号、低噪声的一般原则。对于您的代码,所有括号都是多余的。

【讨论】:

鉴于这是公认的答案,可能值得一提的是,子名称和括号之间的空格很重要。 谢谢@donaldh。这就是我所说的“(名称的末尾和开头的括号之间没有空格)”的意思,但我已经得出结论,我的答案在几个方面是草率的,我希望明天能解决,而实际的代码总是更好不是散文,所以我将添加代码来澄清这一点和/或链接到 Holli 的答案。【参考方案2】:

问题是函数名后面的空格。如果您在此处留出空格,raku 会将括号中的表达式视为一个单独的列表。这里的join会认为你想使用列表作为joiner。

观察:

>raku -e "sub foo( $arg )  say $arg.WHAT ; foo( 'abc', )"
(Str)

>raku -e "sub foo( $arg )  say $arg.WHAT ; foo ( 'abc', )"
(List) 

所以简而言之,如果你想使用括号来调用子,不要在子名称和开始括号之间放置空格。

【讨论】:

【参考方案3】:

见Traps to avoid, 试试:

my @s=("00aabb", "02babe");

say join "A", @s;
say join |("A",@s);
say join("A",@s);
say @s.join: "A";

#or some crazy
say join\ ("A",@s);
say "A".&join: @s;
say join @s: "A";
say "A" [&join] @s;
say @s R[&join] "A";
#…

【讨论】:

【参考方案4】:

A:“不要在函数名和左括号'('之间放置空格”♎️KISS

【讨论】:

以上是关于Raku vs. Perl5,出人意料的结果的主要内容,如果未能解决你的问题,请参考以下文章

Perl 之父同意 Perl 6 改名为 Raku

是否有一些模型可用于理解 Raku 中的容器、引用、原始、rw、\?

以后没有 Perl 6 了!Perl 之父同意改名

为啥我使用这些 Raku 正则表达式会得到不同的回溯?

Perl 7正在路上,6呢?

记一次SQL环境搭建