The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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.

AUTHOR

Thomas R. Wyant, III wyant at cpan dot org

COPYRIGHT

Copyright (C) 2020 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.