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   723 use strict;
  1         3  
  1         34  
4 1     1   6 use warnings;
  1         2  
  1         29  
5              
6 1     1   5 use Perl::Critic::Utils qw(:severities :classification :ppi);
  1         3  
  1         51  
7 1     1   356 use parent 'Perl::Critic::Policy';
  1         2  
  1         6  
8              
9 1     1   68 use List::Util 'any';
  1         3  
  1         58  
10 1     1   445 use Perl::Critic::Freenode::Utils qw(is_empty_return is_structural_block);
  1         3  
  1         75  
11              
12             our $VERSION = '0.030';
13              
14 1     1   7 use constant DESC => 'return called with no arguments';
  1         2  
  1         56  
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         2  
  1         322  
16              
17 11     11 0 50831 sub supported_parameters { () }
18 5     5 1 67 sub default_severity { $SEVERITY_LOWEST }
19 0     0 1 0 sub default_themes { 'freenode' }
20 11     11 1 81915 sub applies_to { 'PPI::Statement::Sub' }
21              
22             sub violates {
23 11     11 1 238 my ($self, $elem) = @_;
24            
25 11   50     49 my $block = $elem->block || return ();
26             my $returns = $block->find(sub {
27 211     211   2173 my ($elem, $child) = @_;
28             # Don't search in blocks unless we know they are structural
29 211 100       511 if ($child->isa('PPI::Structure::Block')) {
30 3 100       14 return undef unless is_structural_block($child);
31             }
32 210 100 100     562 return 1 if $child->isa('PPI::Token::Word') and $child eq 'return';
33 189         451 return 0;
34 11         280 });
35            
36             # Return a violation for each empty return, if any non-empty return is present
37 11 100 66 17   211 if ($returns and any { !is_empty_return($_) } @$returns) {
  17         110  
38 8         20 return map { $self->violation(DESC, EXPL, $_) } grep { is_empty_return($_) } @$returns;
  5         50  
  16         61  
39             }
40            
41 3         46 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 => 2,
73             three => get_stuff(), # oops! function returns empty list if @things is empty
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>