[tpm] Dealing with nested map { grep {} }

Tom Legrady legrady at gmail.com
Tue Sep 26 12:34:58 PDT 2017


I agree about avoiding overuse of $a & $b, but I see this interior of a 
map{} as an extension of the situations where there are normally used. 
There won't be a sort within the map and the map will never be inside a 
sort.

Tom


On 2017-09-26 02:17 PM, Shlomi Fish wrote:
> Hi Tom,
>
> On Tue, 26 Sep 2017 13:53:25 -0400
> Tom Legrady <legrady at gmail.com> wrote:
>
>> 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
>>
> this seems like a good solution but you should not use $a as the name of a
> lexical var. See:
>
> http://perl-begin.org/tutorials/bad-elements/#overuse_dollar_underscore
>
> http://perl-begin.org/tutorials/bad-elements/#vars-a-and-b
>
>
>
>> Tom
>> _______________________________________________
>> toronto-pm mailing list
>> toronto-pm at pm.org
>> http://mail.pm.org/mailman/listinfo/toronto-pm
>
>


More information about the toronto-pm mailing list