I'm wondering what colons have to do with method and function calls in Perl 6. For the record, I am using perl6 version 2015.05-55-gd84bbbc built on MoarVM version 2015.05.
I just saw the following in a Perl6 spec test (S32-io) (I added the comment):
$fh.print: "0123456789A"; # prints '0123456789A' to the file
As far as I can tell, this is equivalent to:
$fh.print("0123456789A"); # prints '0123456789A' to the file
Both of these seem to take multiple arguments and to flatten lists fine:
$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
There must be some reason to have these two different syntaxes. Is there any reason to use one or the other syntax?
I also noticed that we have to use either :
or ()
with print, when used as a method:
$fh.print(@a); # Works
$fh.print: @a; # Works!
$fh.print @a; # ERROR!
There is also some interesting behavior when using a colon with the function print
. In this case, :
and ()
are not equivalent:
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)
Then I tried using print in a script file. This works for prints to standard output:
print @a;
However, this does not print to standard output:
print: @a, @a;
But the method version works fine:
$fh.print: @a, @a; # Prints '0123456789A0123456789A' to the file
I feel like I almost understand this, but I can't put it into words. Could someone please explain these varieties of using print. Also, are these behaviors going to change due to the Great List Refactor?
One of the main reasons to use a colon instead of parens is that it can help declutter your code, by removing one set of parens. Otherwise they are exactly the same.
When you have
print: @a
, what you are really doing is putting a label on the line, and letting the@a
fall-through. Which in the REPL will callsay
with the value.If you don't use parens or a colon on a method call, then the method would get called with no arguments.
You can swap the order of the method, and the invocant if you use a colon.