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

In reply to Re: What should be returned in scalar context? by ihb
in thread What should be returned in scalar context? by tilly

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.