Perl5 -> Perl6: hash, keys and grep


Imagine you have an hash (may be a constant) that contains a set of available running mode, something defined as follows:
my %available_modes =  csv => 'Comma Separated Values',
                       org => 'Emacs-org mode compatible',
                       sql => 'SQL commands',
                      ;

Imagine your application handle a $mode variable that identifies the operating mode among those available as the hash keys. Now you want to run all available modes if no specific mode has been set or if an alien mode has been passed. Here’s how I would do it in Perl 5:
@modes_to_process = sort keys %available_modes if ( ! $mode
                                                   || ! grep( $mode, keys %available_modes ) );
The idea is quite simple: the postfix if checks if $mode has been defined or if it does not appear in the list of keys, and I use the grep operator to achieve that. If none condition is verified, all the sorted keys are used in @modes_to_process. In Perl 6 I’ve achieved the following so far:
    @modes_to_process = %available_modes{}:k.sort if ( %available_modes{}:k.grep( /$mode/ ).elems <= 0 );
Here the idea is somehow simpler, even if the code is a little less readable at glance. The postfix if extracts the keys (thru the k adverb), the list is then grepped with a regular expression consisting only of the $mode variable. The result should produce another list, and if the count of elements is zero than the list is empty (so the grep failed). The adoption of a regular expression based grep has a huge advantage: it does work either when $mode is defined or when it is not. Another, shorter, way is to check if the $mode has been defined and is contained into the hash keys as follows:
my @modes_to_process = %available_modes{}:k.sort if ( ! $mode.defined || ( %available_modes{ $mode }:!exists ) );
the idea here is to use the adverb :!exists (negation of exists) on the hash indexed by $mode. Please note that the adverb has to be parhentesized or it will try to be evaluated as infix instead of circumfix (thanks to Brandon).

The article Perl5 -> Perl6: hash, keys and grep has been posted by Luca Ferrari on September 18, 2017