tags:

views:

142

answers:

3

Is there a difference between a subroutine that does

return;

and one that does

return undef;

?

+5  A: 

Given

sub foo { return; }
sub bar { return undef; }

In scalar context, they behave the same.

my $foo = foo();   # $foo is undef
my $bar = bar();   # $bar is undef

In list context, they behave differently

my @foo = foo();   # @foo is ()  (an empty list)
my @bar = bar();   # @bar is ( undef )  (a one-element list)

Note that a one-element list is a true value in boolean context, even though the only element is undef.

In general, it's usually not a good idea to return undef; from a subroutine, because of how it behaves in context.

friedo
This is why "Perl Best Practices" (and `Perl::Critic`) suggest not using `return undef`.
hillu
@hillu: and it is same reason why sometime it is good idea to use it. For example function is supposed to return logical (boolean) answer and you wish to use it another function call `foo(1, bar(), 2)`. If `bar` would written with `return;` you will be surprised ;-)
Hynek -Pichi- Vychodil
One of the more than a few things PBP gets wrong.
ysth
+15  A: 

return will return an empty list in list context but undef in scalar context. return undef; will always return a single value undef even in list context.

In general, it's usually not a good idea to return undef; from a subroutine normally used in list context:

sub foo { return undef }
if ( my @x = foo() ) {
    print "oops, we think we got a result";
}

In general, it's usually not a good idea to return; from a subroutine normally used in scalar context, because it won't behave as the user expects in list context:

sub foo { return }
%x = ( 'foo' => foo(), 'bar' => 'baz' );
if ( ! exists $x{'bar'} ) {
    print "oops, bar became a value, not a key";
}

Both of these errors happen quite a bit in practice, the latter more so, perhaps because subs that are expected to return a scalar are more common. And if it's expected to return a scalar, it had better return a scalar.

ysth
A: 

I think I still agree with PBP though.

1) You should avoid nesting function calls:

my $result = bar();
foo(1, $result, 2);

2) You should always be explicit (when doing "complicated" things):

foo(1, scalar bar(), 2);
nicomen
1) It's not just nesting function calls. 2) Yes, from the caller's perspective that would be a good thing. From the callee's perspective it shouldn't be counted on.
ysth
1) more examples then?anyway, I believe you would end up with erratic results more often with $ perl -wle 'sub get_values { return undef; }; my @values = get_values; print scalar @values;' 1If you want to be more explicit and proper, there is always Contextual::Return http://p3rl.org/Contextual::Return
nicomen
@nicomen, your `get_values` is intended for use in list context, and as such should _not_ `return undef`. But if you had a `get_value` function that returned a scalar, it should _always_ return a scalar, never an empty list, so it would use `return undef`. See ysth's answer.
cjm