NAME
Perl::Critic::Policy::RegularExpressions::ProhibitEmptyAlternatives - Beware empty alternatives, because they always match.
AFFILIATION
This Policy is stand-alone, and is not part of the core Perl::Critic.
DESCRIPTION
This Perl::Critic policy checks for empty alternatives; that is, things like /a||b/
. The problem with these is that they always match, which is very probably not what you want.
The possible exception is the final alternative, where you may indeed want something like /glass(?es|y|)/
to match 'glass'
, 'glassy'
, or 'glasses'
, though this is not the usual idiom. This policy does not allow empty final alternatives by default, but it can be configured to do so.
Note that empty alternatives are syntax errors in extended bracketed character classes, so this policy treats them as violations no matter how it is configured.
This policy was inspired by y's https://github.com/Perl-Critic/Perl-Critic/issues/727.
CONFIGURATION
This policy supports the following configuration items.
allow_empty_final_alternative
By default, this policy prohibits all empty alternatives, since they match anything. It may make sense, though, to leave the final alternative in a regexp or group empty. For example, /(?:Larry|Moe|Curly|)/
is equivalent to the perhaps-more-usual idiom /(?:Larry|Moe|Curly)?/
.
If you wish to allow this, you can add a block like this to your .perlcriticrc file:
[RegularExpressions::ProhibitEmptyAlternatives]
allow_empty_final_alternative = 1
allow_if_group_anchored
It may make sense to allow empty alternatives if they occur in a group that is anchored on the right. For example,
"What ho, Porthos!" =~ /(|Athos|Porthos|Aramis)!/
captures 'Porthos'
because the regular expression engine sees 'Porthos!'
before it sees '!'
.
If you wish to allow this, you can add a block like this to your .perlcriticrc file:
[RegularExpressions::ProhibitEmptyAlternatives]
allow_if_group_anchored = 1
Caveat: I believe that a full static analysis of this case is not possible when back references or recursions must be considered as anchors. Correct analysis of groups (captures or otherwise) is not currently attempted. In these cases the code assumes that the entity represents an anchor.
ignore_files
It may make sense to ignore some files. For example, Module::Install component inc/Module/Install/Metadata.pm is known to violate this policy, at least in its default configuration -- though it passes if allow_empty_final_alternative
is enabled.
If you wish to ignore certain files, you can add a block like this to your .perlcriticrc file:
[RegularExpressions::ProhibitEmptyAlternatives]
allow_if_group_anchored = inc/Module/Install/Metadata\.pm\z
The value is a regular expression.
SUPPORT
Support is by the author. Please file bug reports at https://rt.cpan.org/Public/Dist/Display.html?Name=Perl-Critic-Policy-RegularExpressions-ProhibitEmptyAlternatives, https://github.com/trwyant/perl-Perl-Critic-Policy-RegularExpressions-ProhibitEmptyAlternatives/issues, or in electronic mail to the author.
AUTHOR
Thomas R. Wyant, III wyant at cpan dot org
COPYRIGHT
Copyright (C) 2020-2021 Thomas R. Wyant, III
LICENSE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.0. For more details, see the full text of the licenses in the directory LICENSES.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.