The above idiom is a simple way of creating a list of unique values from another
list, as the output of the code aptly demonstrates. However, with all those
curly braces it may not be immediately obvious what's going on, so let's break
it down.

The surrounding pair of curly braces creates an anonymous hash which is
populated with they key-value pairs from the map
statement. So we now have a hash reference to an anonymous hash who's keys are the elements from @list, and because hash keys are unique, the keys of the anonymous hash represent a unique set of values.

Finally, with the last pair of curly braces the hash reference to the anonymous hash is dereferenced and we get its list of keys.

Caveats

Because this idiom creates a list, and then a hash, both of which are
immediately disposed of, it's not suited for large lists. Also, because the keys
of a hash aren't ordered, the list of unique values returned will be in a random
order (although this can often be remedied with a simple
sort).

Summary

A short (memory hungry) way to get a list of unique values from a given list.

Yes. Instead of one scalar of the value '1' for every key, you get to share the same undef value for all the keys and thus don't have to allocate tons of memory you aren't going to use anyway. So keys @{{map { $_, undef } @ary}} has the potential to be a lot cheaper than keys @{{map { $_, 1 } @ary}}. The "a lot" part is just related to how many values are in your array. You burn one extra value for every entry in @ary and I'm just suggesting that you don't have to do that in this case.

That would be 2 or more times right? Once ++$seen{$_} == 2 is true, you are immediatelly copying $_ to @doubles. So if it appeared a third time, you couldn't magically remove it again. Your code would be clearer if you used >= to emphasize that.

The following would probably do if you only wanted entries with exactly 2 occurences:

Yep. As I said, it does not iterate on the Perl side. The pertinent nodes in optree are only ever seen once, and the loop is implicit in the execution of that single op. With all other approaches, the pertinent ops have to be dispatched and executed as many times as there are items in the list.

In fact, the keys %{{map{$_=>1}@list}} approach needs to first iterate over all elements of @list for the map, building a list as it goes, then build another list for keys.

In contrast, the @uniq = grep ! $seen{$_}++, @list; approach only builds a list once, while iterating over the elements of @list.

And of course as already explained, undef @seen{@list}; @uniq = keys %seen; just builds a single list - without iterating at all.