I am trying to code 3 echo servers running in promises, but I want to know which promise is doing the echoing. Is there a way to do that?
no strict;
for 0 .. 2 -> $index {
@result[$index] = start {
$myID = $index;
say "======> $myID\n";
my $rsSocket = IO::Socket::INET.new:
localhost => 'localhost',
localport => 1234 + $index,
listen => 1;
while $rsSocket.accept -> $rsConnection {
say "Promise $myID accepted connection";
while $rsConnection.recv -> $stuff {
say "promise $myID Echoing $stuff";
$rsConnection.print($stuff);
}
$rsConnection.close;
}
}
}
await @result;
The echo servers run ok; tested with "nc";
The problem is $myID
becomes 2
after the promises are created, and there is no way for me to tell which promise is doing the current echoing. It seems that $myID
is used by all the promises; is there a way to create variables that are specific to an individual promise?
That's one of the thing you "lose" by going with
no strict
.What you need is lexical scoping. Using
my
will give you a different variable each time the block ({ ... }
) is entered.If you do this:
Then
$myID
will be local to thestart
block, and each time that block is called, it'll remember its id. So you'll get the correct ID whenever the socket receives data.You don't really need to have a
$myID
at all. You can just use$index
in the promise because it has already been scoped to the loop block. Here's a working modification (..with strict on):With that taken care of I feel the urge to point out that using
no strict
seems very unnecessary. Not only does it leave you open to weird scope issues like these, but you gain basically nothing from doing it in your example.Re-enabling strict on your unmodified code and fixing the two compile errors shows have only saved a total of four keystrokes -- at the expense of however many keys you used typing up your question here.