Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: What should be returned in scalar context?

by ihb (Deacon)
on Dec 03, 2003 at 03:54 UTC ( [id://311820]=note: print w/replies, xml ) Need Help??


in reply to What should be returned in scalar context?

I usually just document my functions to be defined in list context only if that's all I've considered. I someone wants to use it in scalar context it's their dare.

Personally I haven't devoloped a default idea for what you ask of, since I haven't had a need to. For instance, if someone just wants the first return value they may do ($foo) = foo(). If someone wants to get a specific element from it they may do (foo())[$n]. If they want it as a reference, they're free to construct one on the fly: [ foo() ]. If [ foo() ] would prove inefficient I'd usually prefer providing another function for getting a reference, e.g. foo_ref(), and not add behaviour to the existing routine.

There is one special case though, and that's for methods that have one-to-one input-to-output list length mapping. If two arguments are taken, two elements are returned. It may then look like

my ($foo, $bar) = burk('foo', 'bar'); my ($foo, $bar, $baz) = burk('foo', 'bar', 'baz');

and in this particular case I can find it DWIMy to let

my ($foo) = burk('foo');

be equivalent to

my $foo = burk('foo');

but

my $foo = burk('foo', 'bar');

would emit a warning, since one can guess that this was unintended.

In real life it could look like this:

my $foo = foo(burk());

and &burk is believed to return just one element. Perhaps the user was wrong in that, and &burk returned more than one element. Or perhaps &burk needed to be called in scalar context to give the expected return behaviour of one element, like localtime(). (Note that this thusly just isn't a short-cut but also imposes extra checks on &burks return.)

To sum it up as a general rule of thumb: If a subroutine has the character of returning a list, but sometimes returns just one element, then it can be made so that in scalar context it returns that very element. But if it's called in scalar context and it in list context would have returned more than one element then it should warn.

Code-wise this means

return @results if wantarray; carp("More than one value in result in scalar context for &foo") if @results > 1; return $results[0];

This whole post was pretty much a condensed revised repost of the relevant things in posts Re: Context aware functions - best practices? and Re: Re: Re: Context aware functions - best practices?. (Both nodes can be worth reading plus demerphq's reply, dispite (or because) their tendency to elaborate and digress.)

Just my thoughts,
ihb

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://311820]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-04-24 22:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found