[tpm] Dealing with nested map { grep {} }
Tom Legrady
legrady at gmail.com
Tue Sep 26 10:53:25 PDT 2017
As an exercise, I'm implementing a RosettaCode challenge for a game
between human and computer.
const my $PLAYERS => qw( human computer );
I want to automatically access the appropriate opponent for each player,
which allows core game logic of
while ( $no_one_won ) {
for my $player ( @PLAYERS ) {
$self->player( $player )->take_turn( $OPPONENT{$player} );
}
}
But to initialize %OPPONENT, I would need to nest a grep{} inside a
map{}, which leads to two instances of $_. Now perhaps the specification
of the opponent should be part of the game object or of a player object,
but I'm still curious how to resolve this problem in a single stage. Now
obviously you can't compare $_ with $_ ...
const my %OPPONENT => map { $_ => grep { $_ ne $_ } @PLAYERS } @PLAYERS
If it weren't a const object, we could do this in stages, though it's
verbose and ugly:
my %OPPONENT;
for my $player ( @PLAYERS ) {
$OPPONENT{$player} = grep { $_ ne $player } @PLAYERS
}
But in the case of 'const my %OPPONENT', it's an error to attempt to
vivify a key after the object has become restricted.
It worked fine if I replaced the inner grep{} with a subroutine call,
not_me(), which would perform the grep away from the map{}. But then it
occurred to me to perform a variable assignment within the map{}. Once
we assign $a, we can safely redefined $_.
const my %OPPONENT => map { my $a = $_; $a => grep { $_ ne $a}
@PLAYERS } @PLAYERS
Tom
More information about the toronto-pm
mailing list