http://www.perlmonks.org?node_id=316305


in reply to Re: Re: Re: Re: Re: What should be returned in scalar context? (best practice)
in thread What should be returned in scalar context?

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