File Coverage

blib/lib/Perl/Critic/Policy/BuiltinFunctions/ProhibitReturnOr.pm
Criterion Covered Total %
statement 26 27 96.3
branch 8 10 80.0
condition 3 3 100.0
subroutine 8 9 88.8
pod 4 4 100.0
total 49 53 92.4


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::BuiltinFunctions::ProhibitReturnOr;
2 2     2   160999 use 5.008_001;
  2         5  
3 2     2   7 use strict;
  2         2  
  2         34  
4 2     2   11 use warnings;
  2         3  
  2         42  
5              
6 2     2   610 use Perl::Critic::Utils;
  2         89150  
  2         35  
7              
8 2     2   1043 use base 'Perl::Critic::Policy';
  2         2  
  2         1062  
9              
10             our $VERSION = "0.01";
11              
12             my $DESCRIPTION = q{Low precedence operator after return is never evaluated};
13             my $EXPLANATION = q{Return has higher precedence than %s, so it returns before evaluating the rest of the expression.};
14             my %PROHIBITED = hashify( qw(or and xor) );
15              
16 5     5 1 32 sub default_severity { return $SEVERITY_MEDIUM }
17 0     0 1 0 sub default_themes { return qw(bugs zr) }
18 9     9 1 42784 sub applies_to { return 'PPI::Token::Word' }
19              
20             sub violates {
21 17     17 1 800 my ($self, $elem) = @_;
22 17 100       39 return unless $elem->content eq 'return';
23 9 50       43 return if is_hash_key($elem);
24              
25 9         396 for (my $sib = $elem->snext_sibling; $sib; $sib = $sib->snext_sibling) {
26              
27             # don't squawk on "return $x if $y or $z" or "return $x unless $y or $z"
28 18 100 100     231 last if $sib->content eq 'if' or $sib->content eq 'unless';
29              
30 16 100       192 next unless $sib->isa('PPI::Token::Operator');
31 5 50       7 if ($PROHIBITED{$sib}) {
32 5         23 my $explain = sprintf($EXPLANATION, $sib->content);
33 5         36 return $self->violation($DESCRIPTION, $explain, $elem);
34             }
35             }
36              
37 4         43 return;
38             }
39              
40              
41             1;
42             __END__
43              
44             =pod
45              
46             =encoding utf-8
47              
48             =head1 NAME
49              
50             Perl::Critic::Policy::BuiltinFunctions::ProhibitReturnOr - Check for "return $x or ..."
51              
52             =head1 DESCRIPTION
53              
54             C<return> when encountered in an expression returns from the enclosing
55             subroutine, without evaluating the rest of the expression. So a
56             lower-precedence operator (C<or>, C<and>, C<xor>) won't get evaluated
57             after a C<return>. This most commonly appears as the mis-idiom:
58              
59             # NO! DON'T DO THIS!
60             return $x or die 'Aaaagh! $x was zero!';
61              
62             Instead, use the higher-precedence C<||> operator, like this:
63              
64             return $x || die 'Aaaagh! $x was zero!';
65              
66             Or separate the two operations, like this:
67              
68             $x or die 'Aaaagh! $x was zero!';
69             return $x;
70              
71             =head1 CONFIGURATION
72              
73             This Policy is not configurable except for the standard options.
74              
75             =head1 LICENSE
76              
77             Copyright (C) 2016 Jeremy Leader.
78              
79             This library is free software; you can redistribute it and/or modify
80             it under the same terms as Perl itself.
81              
82             =head1 AUTHOR
83              
84             Jeremy Leader E<lt>jeremy@ziprecruiter.comE<gt>
85              
86             =head1 SEE ALSO
87              
88             L<Perl::Critic>
89              
90             =cut
91