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',
;
$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 ) );
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 );
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 ) );
:!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).