Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re^2: Use of wantarray Considered Harmful (bad use)

by TGI (Parson)
on Dec 12, 2008 at 21:06 UTC ( #730047=note: print w/replies, xml ) Need Help??

in reply to Re: Use of wantarray Considered Harmful (bad use)
in thread Use of wantarray Considered Harmful

Hear, hear. You make many good points.

return wantarray ? @x : \@x; return wantarray ? @x : $x[0];

I wonder what will happen when one of those two programmers has to work on the other's code.

Both are just bad practice.

The first one is just plain bad. Someone would have to work hard to persuade me that it's a good idea to use it. It costs functionality and doesn't buy anything. If there is a strong need to return an array ref, then why not return the reference every time. If one "needs" a version of the routine that returns a list, wrap the reference-returning version and and give the wrapper a clear name.

I don't think the second usage is necessarily bad practice. This is the same interface used by readline. If there is a good reason not to return the whole list at once (it's huge, your reads are destructive, etc), then this API makes sense.

Context sensitive APIs are like operator overloading and tie. If used properly, they improve the readability of your code. If used badly, life begins to suck. Think carefully before using any of these techniques.

TGI says moo

Replies are listed 'Best First'.
Re^3: Use of wantarray Considered Harmful (bad use)
by Porculus (Hermit) on Dec 12, 2008 at 22:52 UTC
    I don't think the second usage is necessarily bad practice. This is the same interface used by readline.

    Oh no it isn't! (Cue audience...)

    readline returns line 2 on the second call, line 3 on the third call, etc -- and it only reads those lines when they're requested. This is useful, because you can stick it in a while loop and iterate over a potentially large "array" but only hold one element in memory at a time.

    return wantarray ? @x : $x[0]; does nothing so useful. It creates the entire array every single time the sub is called, and then it always returns the same first element. If the whole list is huge, then you're creating the whole huge list anyway. If the reads are destructive, then you just destroyed everything but the first item. Not so useful...

      Oh yes it is! :)

      Granted, if you create your @x by copying the large array you may wish to avoid copying, then it is pretty stupid to use wantarray to avoid making another copy.

      But if you are working with an extant huge @x, its OK.

      With only the one line we have to guess what the provenance of @x is.

      Even if your read is destructive (like from a filehandle, or another similar iterator), there should be no problem. The ternary short circuits, and only one term is evaluated. So @x never gets evaluated in a list context and we have no massive destruction.

      This assumes that you are working with a preexisting @x. If you are destructively copying from some source into @x, then the results will be ugly.

      Anyhow, I think we basically agree that context sensitive return values can be useful to improve an API, but the should be used with care, and that they must be clearly documented. Also that creating an interface similar to readline (without creating massive unneeded copying of data) is a valid use of the technique.

      TGI says moo

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://730047]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2017-05-01 05:59 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (545 votes). Check out past polls.