1 ##############################################################################
2 # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Policy/ValuesAndExpressions/ProhibitMixedBooleanOperators.pm $
3 # $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
6 ##############################################################################
8 package Perl::Critic::Policy::ValuesAndExpressions::ProhibitMixedBooleanOperators;
15 use Perl::Critic::Utils qw{ :severities :data_conversion };
16 use base 'Perl::Critic::Policy';
19 #-----------------------------------------------------------------------------
21 our $VERSION = '1.088';
22 #-----------------------------------------------------------------------------
24 Readonly::Hash my %LOW_BOOLEANS => hashify( qw( not or and ) );
25 Readonly::Hash my %HIGH_BOOLEANS => hashify( qw( ! || && ) );
27 Readonly::Hash my %EXEMPT_TYPES => hashify(
30 PPI::Statement::Scheduled
31 PPI::Statement::Package
32 PPI::Statement::Include
34 PPI::Statement::Variable
35 PPI::Statement::Compound
41 #-----------------------------------------------------------------------------
43 Readonly::Scalar my $DESC => q{Mixed high and low-precedence booleans};
44 Readonly::Scalar my $EXPL => [ 70 ];
46 #-----------------------------------------------------------------------------
48 sub supported_parameters { return () }
49 sub default_severity { return $SEVERITY_HIGH }
50 sub default_themes { return qw( core bugs pbp ) }
51 sub applies_to { return 'PPI::Statement' }
53 #-----------------------------------------------------------------------------
57 my ( $self, $elem, undef ) = @_;
59 # PPI::Statement is the ancestor of several types of PPI elements.
60 # But for this policy, we only want the ones that generally
61 # represent a single statement or expression. There might be
62 # better ways to do this, such as scanning for a semi-colon or
65 return if exists $EXEMPT_TYPES{ ref $elem };
67 if ( $elem->find_first(\&_low_boolean)
68 && $elem->find_first(\&_high_boolean) ) {
70 return $self->violation( $DESC, $EXPL, $elem );
75 #-----------------------------------------------------------------------------
78 my (undef, $elem) = @_;
79 return if $elem->isa('PPI::Statement');
80 $elem->isa('PPI::Token::Operator') || return 0;
81 return exists $LOW_BOOLEANS{$elem};
84 #-----------------------------------------------------------------------------
87 my (undef, $elem) = @_;
88 return if $elem->isa('PPI::Statement');
89 $elem->isa('PPI::Token::Operator') || return 0;
90 return exists $HIGH_BOOLEANS{$elem};
97 #-----------------------------------------------------------------------------
103 Perl::Critic::Policy::ValuesAndExpressions::ProhibitMixedBooleanOperators - Write C< !$foo && $bar || $baz > instead of C< not $foo && $bar or $baz>.
107 This Policy is part of the core L<Perl::Critic> distribution.
112 Conway advises against combining the low-precedence booleans ( C<and
113 or not> ) with the high-precedence boolean operators ( C<&& || !> )
114 in the same expression. Unless you fully understand the differences
115 between the high and low-precedence operators, it is easy to
116 misinterpret expressions that use both. And even if you do understand
117 them, it is not always clear if the author actually intended it.
119 next if not $foo || $bar; #not ok
120 next if !$foo || $bar; #ok
121 next if !( $foo || $bar ); #ok
126 This Policy is not configurable except for the standard options.
131 Jeffrey Ryan Thalhammer <thaljef@cpan.org>
135 Copyright (c) 2005-2008 Jeffrey Ryan Thalhammer. All rights reserved.
137 This program is free software; you can redistribute it and/or modify
138 it under the same terms as Perl itself. The full text of this license
139 can be found in the LICENSE file included with this module.
145 # cperl-indent-level: 4
147 # indent-tabs-mode: nil
148 # c-indentation-style: bsd
150 # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :