Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of colon in method and function calls in Perl 6

Tags:

raku

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?

like image 460
Christopher Bottoms Avatar asked Jun 22 '15 14:06

Christopher Bottoms


Video Answer


1 Answers

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 call say 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.

say $*ERR: 'hello world'; # $*ERR.say('hello world')
like image 123
Brad Gilbert Avatar answered Sep 28 '22 03:09

Brad Gilbert