6

我想知道冒号与 Perl 6 中的方法和函数调用有什么关系。为了记录,我使用的是基于 MoarVM 版本 2015.05 构建的 perl6 版本 2015.05-55-gd84bbbc。

我刚刚在Perl6 规范测试(S32-io)中看到了以下内容(我添加了评论):

$fh.print: "0123456789A";   # prints '0123456789A' to the file

据我所知,这相当于:

$fh.print("0123456789A");   # prints '0123456789A' to the file

这两个似乎都需要多个参数并且可以很好地展平列表:

$fh.print: "012", "345", "6789A";   # prints '0123456789A' to the file
$fh.print("012", "345", "6789A");   # prints '0123456789A' to the file

my @a = <012 345 6789A>;

$fh.print(@a);   # prints '0123456789A' to the file
$fh.print: @a;   # prints '0123456789A' to the file

有这两种不同的语法一定是有原因的。有任何理由使用一种或另一种语法吗?

我还注意到,当用作方法时,我们必须使用:或与 print 一起使用:()

$fh.print(@a);   # Works
$fh.print: @a;   # Works!
$fh.print @a;    # ERROR!

在函数中使用冒号时还有一些有趣的行为print。在这种情况下,:()不等价:

print @a;  # Prints '0123456789A' (no newline, just like Perl 5)
print(@a); # Ditto
print: @a; # Prints '012 345 6789A' followed by a newline (at least in REPL)

print  @a, @a; # Error (Two terms in a row)
print: @a, @a; # Prints '012 345 6789A 012 345 6789A' followed by a newline (in REPL) 

然后我尝试在脚本文件中使用 print 。这适用于打印到标准输出:

print @a;

但是,这不会打印到标准输出:

print: @a, @a;

但方法版本工作正常:

$fh.print: @a, @a; # Prints '0123456789A0123456789A' to the file

我觉得我几乎明白这一点,但我无法用语言表达。有人可以解释这些使用打印的品种吗?另外,这些行为是否会因为 Great List Refactor 而改变?

4

2 回答 2

9

使用冒号而不是括号的主要原因之一是它可以通过删除一组括号来帮助整理代码。否则它们是完全相同的。

当你拥有print: @a时,你真正在做的就是在线上贴上标签,然后让它@a通过。REPL 中的哪个将调用say该值。

如果您在方法调用中不使用括号或冒号,则该方法将在没有参数的情况下被调用。


如果使用冒号,您可以交换方法的顺序和调用者的顺序。

say $*ERR: 'hello world'; # $*ERR.say('hello world')
于 2015-06-22T19:31:05.680 回答
9

只是为了进一步澄清-使用冒号而不是括号是另一种方法调用语法,而不是另一种函数调用语法。将函数或块作为参数传递给方法时非常方便。使用 grep 或 map 是常见的例子——考虑一下;

@measurements.map( { check_accuracy($_); fail "bad value" if $_ < 0 }  );

请注意,我在结束卷曲之后放置了一个额外的空格,以尝试将我传递的函数与关闭方法调用所需的必要语法分开。这段代码的读者完全理解整个块是调用的一个参数,并且通常专注于块的内容将要实现的内容 - 然后遇到我称之为“Lone Paren”的东西 - 就像 Lone Ranger总是与他可信赖的骏马 Silver 在一起,Lone Paren 几乎总是在他可信赖的骏马 Semicolon 旁边。

为什么不把他们两个都扔掉?

如果语句以结束花括号结束,则可选的方法调用语法与分号相结合,使之成为可能;

@measurements.map:  { check_accuracy($_);  fail "bad value" if $_ < 0 }

好多了。
虽然替代方法调用格式是另一种需要学习的语法,但它很容易理解,并且在某些情况下(如上面),可以使生成的代码更清晰、更易于阅读。

于 2016-02-13T10:57:05.420 回答