I encountered this today and thought it prudent to post a Q&A as I couldn't find anything similar.
Feel free to vote-to-close if you find a duplicate of this question.
The following subroutine conditionally return
s output; I consider it "clumsy" because it isn't explicit about what is returned to the caller when the conditional is not satisfied:
sub is_multiple_of_three {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
unless $value % 3;
}
A quick rewrite makes short work of clarifying the (more graceful) subroutine's intended behaviour under all circumstances:
sub is_multiple_of_three {
my ( $value ) = @_ ;
return if $value % 3;
return "$value is a multiple of 3";
}
When calling these both flavours of the subroutine, I was expecting to find some consistency between what both return
in list context:
- a string when the conditional evaluates to true
- nothing (an empty list) when the conditional evaluates to false
But alas, the behaviour was slightly unexpected:
use strict;
use warnings;
use Data::Printer;
use feature 'say';
my %subs = (
graceful => sub {
my ( $value ) = @_ ;
return if $value % 3;
return "$value is a multiple of 3";
},
clumsy => sub {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
unless $value % 3;
},
);
for my $name ( keys %subs ) {
my $sub = $subs{$name};
say $name;
my @results = map { $sub->($_) } 1 .. 10;
p @results;
}
Output
graceful
[
[0] "3 is a multiple of 3",
[1] "6 is a multiple of 3",
[2] "9 is a multiple of 3"
]
clumsy
[
[0] 1,
[1] 2,
[2] "3 is a multiple of 3",
[3] 1,
[4] 2,
[5] "6 is a multiple of 3",
[6] 1,
[7] 2,
[8] "9 is a multiple of 3",
[9] 1
]
Question
The "graceful" flavour behaves as expected, but why is the "clumsy" sub returning back integers when the conditional is false?