In Perl 6, there is a predefined class Channel, which includes, among the others, the send and the receive methods. Here is the simplest example, where an integer number first is being sent to the channel $c and is then immediately read from it.
my $c = Channel.new; $c.send(42); say $c.receive; # 42
A channel can be passed to a sub as any other variable. Should you do that, you will be able to read from that channel in the sub.
my $ch = Channel.new; $ch.send(2017); func($ch);Â sub func($ch) { Â Â Â say $ch.receive; # 2017 }
It is possible to send more than one value to a channel. Of course, you can later read them all one by one in the same order as they were sent.
my $channel = Channel.new;Â # A few even numbers are sent to the channel. for <1 3 5 7 9> { Â Â Â $channel.send($_); }Â # Now, we read the numbers until the channel has them. # "while @a -> $x" creates a loop with the $x as a loop variable. while $channel.poll -> $x { Â Â Â say $x; }Â # After the last available number, Nil is returned. $channel.poll.say; # Nil
In the last example, instead of the previously used receive method, another one is used: $channel.poll. The difference lies in how they handle the end of the queue. When there are no more data in the channel, the receive will block the execution of the programme until new data arrive. Instead, the poll method returns Nil when no data are left.
To prevent the programme from hanging after the channel data is consumed, close the channel by calling the close method.
$channel.close; while $channel.receive -> $x { Â Â Â say $x; }
Now, you only read data, which are already in the channel, but after the queue is over, an exception will occur: Cannot receive a message on a closed channel. Thus either put a try block around it or use poll.
$channel.close; try { Â Â Â while $channel.receive -> $x { Â Â Â Â Â Â Â say $x; Â Â Â } }
Here, closing a channel is a required to quit after the last data piece from the channel arrives.