Returning 'false' (sometimes)

That behavior needs to be documented very carefully as it has a subtle bug which people keep stumbling over. Most of the time it works:

if ( my $result = foo() ) {... }

But what if, for example, you want to accumulate results so you decide to use an array?

if ( my @results = foo() ) {... }

Congrats! If &foo return false, you now have a one-element array which, in this context, evaluates as true. This is very likely a bug. You can accomplish the same thing, probably bug free, if you just use a bare return:

sub foo { return unless bar(@_); return $something_else;}

From perldoc -f return:

If no EXPR is given, returns an empty list in list context, the undefined value in scalar context, and (of course) nothing at all in a void context.

In other words, if you wish to return 'false', a bare return will Do The Right Thing.

The only significant objection this I can recall hearing is the following:

if ( some_func(1, foo(), 2) ) {... }

Because that's in list context, if &foo has a bare return, &foo returns the empty list and &some_func receives (1, 2). I don't see this happening too often, but you can get around it by forcing scalar context.

if ( some_func(1, scalar foo(), 2) ) {... }

Now &some_func will receive (1, undef, 2).

Also, if you're returning from a ternary operator, you can get the same behavior with this:

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.

Please Log In to Continue

We recently hit against a bug with this the opposite way round. The JSON [cpan.org] module's objToJson function takes a Perl data structure and returns a Json string representation of it. But if the input is undef then it uses bare return.

The bug was that this return value was being used in the parameter list of another function, and the bare return meant there was a argument missing.

Once we'd spotted the bug it was simple to put scalar before the call to objToJson, but it was subtle. If a function is documen