package Perl::Critic::Policy::Community::EmptyReturn; use strict; use warnings; use Perl::Critic::Utils qw(:severities :classification :ppi); use parent 'Perl::Critic::Policy'; use List::Util 'any'; use Perl::Critic::Community::Utils qw(is_empty_return is_structural_block); our $VERSION = 'v1.0.3'; use constant DESC => 'return called with no arguments'; 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.'; sub supported_parameters { () } sub default_severity { $SEVERITY_LOWEST } sub default_themes { 'community' } sub applies_to { 'PPI::Statement::Sub' } sub violates { my ($self, $elem) = @_; my $block = $elem->block || return (); my $returns = $block->find(sub { my ($elem, $child) = @_; # Don't search in blocks unless we know they are structural if ($child->isa('PPI::Structure::Block')) { return undef unless is_structural_block($child); } return 1 if $child->isa('PPI::Token::Word') and $child eq 'return'; return 0; }); # Return a violation for each empty return, if any non-empty return is present if ($returns and any { !is_empty_return($_) } @$returns) { return map { $self->violation(DESC, EXPL, $_) } grep { is_empty_return($_) } @$returns; } return (); } 1; =head1 NAME Perl::Critic::Policy::Community::EmptyReturn - Don't use return with no arguments =head1 DESCRIPTION Context-sensitive functions, while one way to write functions that DWIM (Do What I Mean), tend to instead lead to unexpected behavior when the function is accidentally used in a different context, especially if the function's behavior changes significantly based on context. This also can lead to vulnerabilities when a function is intended to be used as a scalar, but is used in a list, such as a hash constructor or function parameter list. C with no arguments will return either C or an empty list depending on context. Instead, return the appropriate value explicitly. return; # not ok return (); # ok return undef; # ok sub get_stuff { return unless @things; return join(' ', @things); } my %stuff = ( one => 1, two => get_stuff(), # oops! function returns empty list if @things is empty three => 3, ); Empty returns are permitted by this policy if the subroutine contains no explicit return values, indicating it is intended to be used in void context. =head1 CAVEATS This policy currently only checks return statements in named subroutines, anonymous subroutines are not checked. Also, return statements within blocks, other than compound statements like C and C, are not considered when determining if a function is intended to be used in void context. Any non-empty return will cause empty returns within the same subroutine to report violations, even though in list context, C and C are functionally equivalent. It is recommended to explicitly specify an empty list return with C in a function that intends to return list context. =head1 AFFILIATION This policy is part of L. =head1 CONFIGURATION This policy is not configurable except for the standard options. =head1 AUTHOR Dan Book, C =head1 COPYRIGHT AND LICENSE Copyright 2015, Dan Book. This library is free software; you may redistribute it and/or modify it under the terms of the Artistic License version 2.0. =head1 SEE ALSO L