Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Returning undef: The point I would like Damian to reconsider

by merlyn (Sage)
on Jun 22, 2007 at 21:06 UTC ( [id://622910]=note: print w/replies, xml ) Need Help??


in reply to Returning undef: The point I would like Damian to reconsider

Don't change subroutine results based on list or scalar context.
If I were trying to follow that advice, what should I do if a subroutine that returns a list in a list context gets called instead in a scalar or void context? "die"?

Just trying to think this through.

Or did you actually mean "if your subroutine naturally returns a scalar, be sure to return that same scalar in a list context unless otherwise documented" or something convoluted like that?

And the timing for this couldn't be better... I'm just now putting the finishing touches on the Perl Best Practices full-day course that I'm presenting at YAPC::NA next week, and have had my own thoughts on many issues such as these during the writing of the course.

  • Comment on Re: Returning undef: The point I would like Damian to reconsider

Replies are listed 'Best First'.
Re^2: Returning undef: The point I would like Damian to reconsider
by jdporter (Paladin) on Jun 22, 2007 at 21:57 UTC

    In the past, when faced with this question, I've usually gone on the principle that if a function normally/ever gets called in list context, then it should always return a "list", even in scalar context, i.e. if called in scalar context return the last value in its return expression. This, imho, is the minimally surprising behavior in most scenarios, and is also easiest to code as you don't have to code for sensitivity to calling context. OTOH, obviously there may be times when you'd rather have some other behavior; the only other one you should "reasonably" implement is having it act like an array, i.e. return the return list length when called in scalar context. But even that would warrant documentation including several exclamation points. Any other behaviors should, I think, be limited strictly to internal function calls, not in a public interface.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight
      then it should always return a "list", even in scalar context, i.e. if called in scalar context return the last value in its return expression.
      Ugh, that's not possible. You cannot return a list in a scalar context. Ever.

      You can type:

      return (99, 100, 101);
      But that's not "returning a list in a scalar context", even if called in a scalar context. It's returning a scalar in a scalar context, by evaluating that comma-expression in a scalar context, getting the result 101.

      I know you know that, but sloppy language here gets us running around in circles.

      See my On Scalar Context for samples of many things that "listy" things do in a scalar context. Based on that, I don't see how "last thing" is any more intuitive than "first thing" or "number of elements" (the three main candidates).

        WTF (that's "why") do you think I put "list" in quotes?

        When I say "list", everyone (including you) understands what I'm talking about. Give it a rest.

        More importantly, let's stick to the topic at hand. I intend to.

Re^2: Returning undef: The point I would like Damian to reconsider
by martin (Friar) on Jun 23, 2007 at 09:03 UTC
    Don't change subroutine results based on list or scalar context.

    If I were trying to follow that advice, what should I do if a subroutine that returns a list in a list context gets called instead in a scalar or void context? "die"?

    Coercing a strictly list returning function into returning a scalar would be wrong and could be treated as an error of the caller if detected.

    But you caught me there, the subroutine would still need to be context-aware to detect that situation. The impact on the subroutine code could be kept at bay, though, if we tucked that piece of logic away, say, in a listonly convenience function. Is something like that already on CPAN? Hmmmm...

      use Contextual::Return; use Carp qw(croak); ... sub foo { ... return LIST { some listy expression here } SCALAR { croak "please invoke me in a list context" } ; }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2024-04-16 06:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found