1. List::MoreUtils の中身そのまんま
sub uniq (@) { my %h; map { $h{$_}++ == 0 ? $_ : () } @_; }
# grepがこの様なケースの為に存在するのに何故mapで?

2. 定番
%h ;
@uniq = grep { ! $h{$_}++ } @arr ;

3. ハッシュに突っ込んでkeys
%h ;
@h{@arr} = (1) x @arr ;
@uniq = keys %h ;

…手間は一番掛ると思う。