NAME
Perl::Critic::Policy::Subroutines::RequireConsistentReturn - If a return statement is needed anywhere, all returns should be explicit.
DESCRIPTION
Require subroutines that return any values to terminate explicitly with one of: confess, croak, die, exec, exit, goto, return, throw, ....
The final statement of a subroutine establishes a pattern for its use, with no final return interpreted as an 'action', having side effects only. If the last statement of a subroutine is an expression, however, it is unclear if the intent is only side effects or implicit return (see perlsub). To establish consistency, any subroutine returning a value anywhere should use an explicit return everywhere.
Note that implicit return is a violation only when an explicit value-return appears in the subroutine.
The following subroutine definitions are all valid (note that the surrounding sub name {...} is exclued for brevity):
7; # implicit return only
return 7; # explicit return is okay
if($condition) {1} else {2} # both are implicit returns
if($c) {return 1}; die "!" # dying is an explicit statement of intent
my %h=(return=>1); %h; # hash key is not an early-return statement
By contrast, these are violations:
if($condition) {return 1}; 5;
if($condition) {return 1} else {2}
if($condition) {1} else {return 2}
CONFIGURATION
By default, a bare return; statement is considered a "block exit" not a value return. This is not considered a violation:
if($condition) { return }
5;
Bare return statements can be interpreted as value returns by setting:
[Subroutines::RequireConsistentReturn]
bare = 1
The above example would become a violation and need resolved as:
if($condition) { return }
return 5;
NOTES
According to perlsub, "if the last statement is a loop control structure..., the returned value is unspecified". This is an explicit programmer choice, such as when the expected return values are declared within the loop, so these are not considered violations. See "SEE ALSO" to enforce returns after such loops.
BUGS
Possibly.
SEE ALSO
Subroutines::RequireFinalReturn has similar behavior but universally requires a return. For example, it consider these violations:
sub aa() { 5 } # this won't be inlined if changed to 'return 5'
sub aa { foreach (1..3) { 1 } } # explicit unspecified return is not ignored
Perl::Critic::Policy::BuiltinFunctions::ProhibitReturnOr
Perl::Critic::Policy::Community::ConditionalImplicitReturn
Perl::Critic::Policy::Community::EmptyReturn
Perl::Critic::Policy::Mardem::ProhibitReturnBooleanAsInt
Perl::Critic::Policy::ProhibitOrReturn
Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef