What that's doing is known as a hash slice. It's a shorthand for:
$o{'a'} = $a;
$o{'b'} = $b;
$o{'c'} = $c;
<GUESS>The reason for the @ symbol is because assigning values from one ordered list to another. (Hashes are unordered, so you have to order them, especially if you want this to be an rvalue.)</GUESS> | [reply] [d/l] |
| [reply] [d/l] |
| [reply] |
this is called a hash slice.
someone has declared o as a hash, and wants to set up 3 elements in semi-odd way.
it's equivalent to
%o= (a=>'a',
b=>'b',
c=>'c');
except that you can't declare a hash under strict this way -- you still need to explicity code my %o, and then use the hash slice.
So what's it good for?
Primarily when you're populating an array from a hash, and you only want to use a subset of the hash's values. It can be onerous to type @ary=($hash{e}, $hash{f}, ... $hash{n}), if you only wanted those particular elements, so the almight Wall-Oz gave us the hash slice, which reduces the assignment to @ary=@hash{"e".."n"}
(yes, there are other ways of doing this, I acknowledge)
Here's a small example for you showing the hash slice in action :
use strict;
my %o;
@o{qw(a b c d e f)} = (1,2,3,4,5);
my @foo;
@foo=@o{"c".."e"};
print @foo;
the third line uses a hash slice to assign 5 values to %o.
the fifth line uses a hash slice to easily take 3 elements from %0, and assign their values into @foo.
Also, even though I haven't demonstrated it, using @o("a","e","f")
is just as legal.
See also array slices for a similar concept, but with arrays.
update : hey, neat!
@foo=@bar{sort keys %bar}; | [reply] [d/l] [select] |
So, why can't you intialize a slice under 'use strict'? In fact, even under 'no strict', you can't initialize a slice with 'my' nor 'our'. Same thing with array slices.
I ran into this restriction recently, and was just curious as to the reason.
-jehuni
| [reply] |
| [reply] |
I frequently use hash slices to eliminate duplicates from an array.
A simplified example:
my @a = (1,2,3,2,1);
my %a;
@a{@a} = (1) x @a;
my @unique_a = keys %a;
Of course, this does not preserve the order of the elements as they were in original array @a. | [reply] [d/l] |
Perhaps grep might work better here?
my @a = (1,2,3,2,1);
my %seen;
my @unique_a = grep {!$seen{$_}++} @a;
print "A: $_\n" for (@a);
print "Unique: $_\n" for (@unique_a);
Assuming you wanted
to keep the first occurance, this will preserve the original order.
Or you can use map to create your %a hash.
my @a = (1,2,3,2,1);
my %a = map {$_=>1} @a;
my @unique_a = keys %a;
print "A: $_\n" for (@a);
print "Unique: $_\n" for (@unique_a);
-Blake | [reply] [d/l] [select] |