I just upgraded to Perl 5.26.1, now I get
Smartmatch is experimental at check_tr.pl line 67.
where the code in question is
my @patterns = (qr/summary:\s+(.+?) in\s+(.+?) - average of\s+(.+?)$/,
qr/summary:\s+(.+?) in\s+(.+) (.+? .+?)$/);
my $r = "";
opendir(DIR, $dir) or die $!;
while(my $file = readdir(DIR)) {
next if ($file =~ m/^\./);
open(F, '<', "$dir/$file") or die $!;
if (<F> ~~ @patterns) {
$r .= <F>;
...
Question
Ideally with as few changes to the code as possible. What should I do instead of smart matching?
Just spell out what you mean. E.g. if you want to check whether the header line matches any regex in @patterns
:
use List::Util 'any';
...
my $line = <F>;
if (any { $line =~ $_ } @patterns) { ... }
Though in that case, it might be more sensible to pre-compile a single pattern such as:
my ($pattern) = map qr/$_/, join '|', @patterns;
...
if (<F> =~ $pattern) { ... }
If your @patterns
array contains different kinds of data, you might want to choose a different matching operator, e.g. ==
or eq
. If the @patterns
are not all the same “type” and you really want the smartmatch behaviour, you can silence the warning and continue to use it:
use experimental 'smartmatch';
However, this might then break without further warnings in the future.
The reason Smartmatch is experimental is that it is so hard to figure out what it will do without referencing the Docs. Even so, how do we interperet the above code?
Is this a case of:
ARRAY1 ARRAY2 recurse on paired elements of ARRAY1 and ARRAY2[2]
like: (ARRAY1[0] ~~ ARRAY2[0])
&& (ARRAY1[1] ~~ ARRAY2[1]) && ...
Where we presume <F>
is interpreted in list context and emptied in a single call?
Or is this a case of:
Any ARRAY smartmatch each ARRAY element[3]
like: grep { Any ~~ $_ } ARRAY
I'm going to guess the 2nd. In which case the snippet above from the docs gives you an excellent (and clearer) coding alternative. Presuming @patterns
contains regexes, you can also replace the ~~
with =~
.
If you don't like the grep
alternative from the docs, I'd recommend looking into either List::Util
or List::MoreUtils
. Both contain an any
call which acts as a short-circuiting grep
. Alternatively, if you are trying to implement the ARRAY1 ARRAY2
option, the later library contains a pairwise
call that may serve.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With