Syntactic Confectionery Delight PerlMonks

### Re: Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)

by jarich (Curate)
 on Dec 22, 2003 at 04:51 UTC ( #316305=note: print w/replies, xml ) Need Help??

Now let me try this:

```sub f1 { return (33, 42) }
sub f2 { return my @x = (33, 42) }

my \$nelts = f1();    # apparently returns number of elements (2)
my (\$first) = f1();  # apparently returns first element (33)

my \$last = f2();     # apparently returns last element (42)
my (\$first2) = f2();  # apparently returns first element (33)

print "nelts: \$nelts    (expecting 2)\n";
print "first: \$first    (expecting 33)\n";
print "last: \$last      (expecing 42)\n";
print "first2: \$first2  (expecting 33)\n";

Let's run that shall we?

```# Output:
nelts: 42    (expecting 2)
first: 33    (expecting 33)
last: 2      (expecing 42)
first2: 33  (expecting 33)

Hmm. So your suggestion that you can know how it will act isn't even quite true for yourself. But only because you got your examples backwards.

It's interesting though, because I never really bothered noticing a different between the two return options. What you're saying is that if you give return an array then the returned value gives you the number of elements in the list when taken in scalar context. Whereas if you give return a list then the return value gives the final element of the list in scalar context.

An unfortunate inconsistency and one which probably causes many subtle bugs.

To document that the first returns a list and the second returns an array is perfectly acceptable

I understand why you're arguing that there is a distinction between these two cases and I can guess why you feel its better to describe the second as returning an array. However I do agree that the statement is technically incorrect. The subroutine may be returning as an array but what you get back on the other side is a list until you copy it into an array. And you want it to be a list too, as there's very little value of even thinking of it being an array except for the fact that you can take it in scalar context to get the number of elements.

Since the issue is on semantics and your attempt to denote a difference between the two ways of returning a list, I cannot recommend a better choice for how you should document this. I would say that the subroutine returns a list or the number of elements in that list in scalar context, rather than saying it returns an array. But I can understand, even if I don't agree, your reasons for your choice of words.

I'm now going to have to take especial care in future, when calling subroutines which return lists in scalar context. Will I be getting the final value of the length of the list, because I suspect I usually assume the latter.

jarich

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)
by sauoq (Abbot) on Dec 22, 2003 at 07:30 UTC

First, thanks for catching the fact that I had my examples switched. As I explain in my update, I edited my description and failed to switch my examples to match. Good catch and I appreciate your close attention.

An unfortunate inconsistency and one which probably causes many subtle bugs.

No, this is not an inconsistency. It is, in fact, consistent:

```\$ perl -le 'print scalar(33, 42)'
42
\$ perl -le 'print scalar(my @x = (33, 42))'
2
It is well understood that list literals do not act like arrays in scalar context. The expression is evaluated in the proper context before it is returned.

But I can understand, even if I don't agree, your reasons for your choice of words.

I'm not sure you actually do, although you are making an effort to and I appreciate that. Let me see if I can better explain the point that others have so completely missed. When I say, "this sub returns an array," my meaning is very specific and clear. The sub explicitly or implicitly return()s an array. What return() does is already clearly documented in perldoc perlfunc and it is not my responsibility nor would it be prudent for me to duplicate that documentation.

Let's say I document that the sub "returns a list or the number of elements in that list in scalar context" as you suggest. If the developers decide that return() should behave differently, my documentation may become incorrect. If I say simply that my function "returns an array" and a change is made to return()'s behavior, I don't need to change my documentation. It remains correct. Granted, the likelihood of return() changing is pretty much non-existent... but that's completely beside the point. My documentation methodology is perfectly sound.

```-sauoq
"My two cents aren't worth a dime.";
```

Create A New User
Node Status?
node history
Node Type: note [id://316305]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2018-05-21 23:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
World peace can best be achieved by:

Results (163 votes). Check out past polls.

Notices?