perllocaluniq

sub uniq { my %seen; grep !$seen{$_}++, @_ } : No longer allowed. Fix?


Please read first the UPDATE below !!!!

As can be seen elsewhere on stackoverflow, the following perl sub has been popular for some years for extracting the unique elements of a list

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

However, since some recent perl version, the above code produces the error

syntax error at line 2, near "sub uniq "
Can't use global $_ in "my" at test5.pl line 2, near "{$_"
syntax error at test5.pl line 2, near "++,"

and @_ is similarly disallowed. There is various advice to be found that one should use "local $_" and some such, but I cannot get it to work. Also it seems that maybe sub uniq needs to become a function that returns the unique list?

In short: What does the canonical one-liner/function/sub uniq definition look like now? (perl 5.34)

UPDATE: user hobbs had the right idea. It was a typo/syntax error, namely a missing semicolon. A simple example (contrived but makes the point) to generate the error message is to feed the following two lines into perl

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

And to make the error message go away, just add the semicolon

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

The error message seemed very "realistic" to me, so I overlooked the possibility of a simple syntax error. Hopefully I can be forgiven :). If nothing else this post can serve as en example that a seemingly very relevant error message should not always be taken literally.


Solution

  • I think you just made a typo somewhere. There's nothing wrong with that function, and I've tested it to work both on 5.34.0 and blead using the code copied out of your question. I would probably use List::Util::uniq (or uniqnum or uniqstr in special cases) or List::UtilsBy::uniq_by, but nothing has changed in Perl to break that snippet.