pglenski has asked for the wisdom of the Perl Monks concerning the following question:

I found this code on your site I copied to my system and I get these errors. This was to return a unique string. Any ideas?
syntax error at 3.pl line 5, near "%tmp{" syntax error at 3.pl line 7, near "}" Execution of 3.pl aborted due to compilation errors.
#!/usr/bin/perl sub unique { my $self=shift; my %tmp; map { %tmp{$_}=1 } @_; return keys %tmp; } @array = qw(apples cheeries apples bananas apples); $o->unique(@array);

Replies are listed 'Best First'.
Re: compile errors
by tirwhan (Abbot) on Feb 24, 2006 at 23:23 UTC

    To access a hash element you need to use $hash{key}, not %hash{key}. So change

    map { %tmp{$_}=1 } @_;

    to

    map { $tmp{$_}=1 } @_;

    Or consider using the uniq function from List::MoreUtils (which has the added benefit of preserving order in your array).


    All dogma is stupid.
Re: compile errors
by InfiniteSilence (Curate) on Feb 24, 2006 at 23:31 UTC
    "on your site"...

    Who's code was it?

    Code corrections:

    #!/usr/bin/perl -w use strict; my $o; sub unique { my $self=shift; my %tmp; map { $tmp{$_}=1 } @_; return keys %tmp; } my @array = qw(apples cheeries apples bananas apples); #$o->unique(@array); print unique(@array); 1;
    $o->unique means you are calling the unique method of the $o object, which your code doesn't show being instantiated anywhere. The problem you listed was with the %tmp, which is basically incorrect syntax when you are trying to assign a value to a hash element.

    Celebrate Intellectual Diversity

Re: compile errors
by ayrnieu (Beadle) on Feb 25, 2006 at 01:05 UTC
    #! /usr/bin/env perl package Foo; use strict; use warnings; sub new { bless {}, shift } sub uniq { shift; my %h; $h{$_}++ for @_; grep { $h{$_} == 1 } keys %h + } package main; print "@{[Foo->new->uniq(@ARGV)]}\n";
    ...
    ./11911 hi hi hi hey lo hey may ':-)' may lo :-)

      If I am not mistaken, that removes even the first instance of any entry that has a duplicate. Usually one wants to remove only subsequent entries, leaving the first. For that, cache the count on the fly:

      sub uniq { my %cache; return grep { not $cache{$_}++ } @_ }
      print join " ", uniq qw(foo bar baz foo quux foo wibble bar quux wibble bongo foo dazzle);
      Results:
      foo bar baz quux wibble bongo dazzle