File Coverage

blib/lib/Perl/Critic/Policy/Freenode/EmptyReturn.pm
Criterion Covered Total %
statement 41 42 97.6
branch 8 8 100.0
condition 6 8 75.0
subroutine 14 15 93.3
pod 4 5 80.0
total 73 78 93.5


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Freenode::EmptyReturn;
2              
3 1     1   665 use strict;
  1         2  
  1         36  
4 1     1   6 use warnings;
  1         2  
  1         29  
5              
6 1     1   6 use Perl::Critic::Utils qw(:severities :classification :ppi);
  1         2  
  1         51  
7 1     1   396 use parent 'Perl::Critic::Policy';
  1         2  
  1         5  
8              
9 1     1   54 use List::Util 'any';
  1         2  
  1         69  
10 1     1   443 use Perl::Critic::Freenode::Utils qw(is_empty_return is_structural_block);
  1         4  
  1         77  
11              
12             our $VERSION = '0.033';
13              
14 1     1   7 use constant DESC => 'return called with no arguments';
  1         11  
  1         63  
15 1     1   6 use constant EXPL => 'return with no arguments may return either undef or an empty list depending on context. This can be surprising for the same reason as other context-sensitive returns. Return undef or the empty list explicitly.';
  1         3  
  1         326  
16              
17 11     11 0 60646 sub supported_parameters { () }
18 5     5 1 64 sub default_severity { $SEVERITY_LOWEST }
19 0     0 1 0 sub default_themes { 'freenode' }
20 11     11 1 99253 sub applies_to { 'PPI::Statement::Sub' }
21              
22             sub violates {
23 11     11 1 256 my ($self, $elem) = @_;
24            
25 11   50     45 my $block = $elem->block || return ();
26             my $returns = $block->find(sub {
27 211     211   2662 my ($elem, $child) = @_;
28             # Don't search in blocks unless we know they are structural
29 211 100       587 if ($child->isa('PPI::Structure::Block')) {
30 3 100       13 return undef unless is_structural_block($child);
31             }
32 210 100 100     687 return 1 if $child->isa('PPI::Token::Word') and $child eq 'return';
33 189         569 return 0;
34 11         308 });
35            
36             # Return a violation for each empty return, if any non-empty return is present
37 11 100 66 17   207 if ($returns and any { !is_empty_return($_) } @$returns) {
  17         113  
38 8         22 return map { $self->violation(DESC, EXPL, $_) } grep { is_empty_return($_) } @$returns;
  5         58  
  16         73  
39             }
40            
41 3         55 return ();
42             }
43              
44             1;
45              
46             =head1 NAME
47              
48             Perl::Critic::Policy::Freenode::EmptyReturn - Don't use return with no
49             arguments
50              
51             =head1 DESCRIPTION
52              
53             Context-sensitive functions, while one way to write functions that DWIM (Do
54             What I Mean), tend to instead lead to unexpected behavior when the function is
55             accidentally used in a different context, especially if the function's behavior
56             changes significantly based on context. This also can lead to vulnerabilities
57             when a function is intended to be used as a scalar, but is used in a list, such
58             as a hash constructor or function parameter list. C<return> with no arguments
59             will return either C<undef> or an empty list depending on context. Instead,
60             return the appropriate value explicitly.
61              
62             return; # not ok
63             return (); # ok
64             return undef; # ok
65              
66             sub get_stuff {
67             return unless @things;
68             return join(' ', @things);
69             }
70             my %stuff = (
71             one => 1,
72             two => get_stuff(), # oops! function returns empty list if @things is empty
73             three => 3,
74             );
75              
76             Empty returns are permitted by this policy if the subroutine contains no
77             explicit return values, indicating it is intended to be used in void context.
78              
79             =head1 CAVEATS
80              
81             This policy currently only checks return statements in named subroutines,
82             anonymous subroutines are not checked. Also, return statements within blocks,
83             other than compound statements like C<if> and C<foreach>, are not considered
84             when determining if a function is intended to be used in void context.
85              
86             Any non-empty return will cause empty returns within the same subroutine to
87             report violations, even though in list context, C<return> and C<return ()> are
88             functionally equivalent. It is recommended to explicitly specify an empty list
89             return with C<return ()> in a function that intends to return list context.
90              
91             =head1 AFFILIATION
92              
93             This policy is part of L<Perl::Critic::Freenode>.
94              
95             =head1 CONFIGURATION
96              
97             This policy is not configurable except for the standard options.
98              
99             =head1 AUTHOR
100              
101             Dan Book, C<dbook@cpan.org>
102              
103             =head1 COPYRIGHT AND LICENSE
104              
105             Copyright 2015, Dan Book.
106              
107             This library is free software; you may redistribute it and/or modify it under
108             the terms of the Artistic License version 2.0.
109              
110             =head1 SEE ALSO
111              
112             L<Perl::Critic>