SSilk
SSilk

Reputation: 2502

How is this perl sub function returning anything?

I've been using the implementation of uniq shown here for a couple of years in various scripts, and I just realized I don't understand how it's returning an array.

That implementation is as follows:

sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}

my @array = qw(one two three two three);
my @filtered = uniq(@array);

Can someone explain how that two line sub is returning an array that gets assigned to @filtered? I.e. why do we not need to take some result from the grep line and return it?

Looking at the sub itself in isolation, my assumption would have been that the grep line was operating on an array passed by reference, @_, and that the calling line could just be uniq(@array);, with @array being modified after that call.

This is purely for my own understanding, I've got no beef with the functionality of this sub, which I've been using with great success.

Upvotes: 0

Views: 85

Answers (2)

Dave Cross
Dave Cross

Reputation: 69224

It's not clear which part of the subroutine you're not understanding. But before we look at the subroutine, a brief aside about terminology.

In Perl "lists" and "arrays" are two different things. And a subroutine only ever returns a list, not an array. The fact that you then store the returned list into the array @filtered makes no difference - what you originally got back from the subroutine was a list.

With that in mind, let's look at your subroutine.

You pass in the array, @array. The contents of that array are put into @_ and passed to the subroutine.

You then use grep on your input array, @_. grep acts as a list filter - it takes a list as input and returns a (probably shorter) list as output. So you get a list of values as the output from grep.

As your subroutine doesn't have an explicit return statement, it returns the value of the final statement executed in the subroutine. That's the grep statement, so the subroutine returns the list that was returned from the grep.

You then take the list that was returned from your subroutine and store it in @filtered.

Does that help at all?

Upvotes: 2

Quentin
Quentin

Reputation: 943108

why do we not need to take some result from the grep line and return it

You do, and are. See perldoc perlsub:

If no "return" is found and if the last statement is an expression, its value is returned.

Upvotes: 7

Related Questions