Perl has three built in different data types:
- Scalar (as in
$foo
).
- Arrays (as in
@foo
).
- Hashes (as in
%foo
).
The problem is that each of these deal with single bits of data. Sure, there can be lots of items in list and hashes, but they are lots of single bits of data.
Let's say I want to keep track of people. People have a first name, last name, phone, etc. Let's define a person:
my %person;
$person{FIRST_NAME} = "Bob";
$person{LAST_NAME} = "Smith";
$person{PHONE_NUMBER} = "555-1234";
Okay, now I need to store another person. Do I create another hash? What if I could have, say an array of hashes with each hash representing a single person?
Perl allows you to do this by making a reference to the hash:
my @list;
push @list, \%person;
THe \%person
is my reference to the memory location that contains my hash. $list[0]
points to that memory location and allows me to access that person through dereferencing.
Now, my array contains my person. I can create a second one:
$person{FIRST_NAME} = "Susan";
$person{LAST_NAME} = "Brown";
$person{PHONE_NUMBER} = "555-9876";
push @list, \%person.
Okay, how do I reference my person. In Perl, you dereference by putting the correct sigil in front of your reference. For example:
my $person_ref = @list[0]; #Reference to Bob's hash
my %person = %{person_ref}; #Dereference to Bob's hash. %person is now Bob.
Several things, I'm doing a lot of moving data from one variable to another, and I am not really using those variables. Let's eliminate the variables, or at least their names:
my @list;
push @list, {}; #Anonymous hash in my list
$list[0]
still points to a reference to a hash, but I never had to give that hash a name. Now, how do I put Bob's information into it?
If $list[0]
is a reference to a hash, I could dereference it by putting %{...}
around it!
%person = %{ $list[0] }; #Person is an empty hash, but you get the idea
Let's fill up that hash!
${ $list[0] }{FIRST_NAME} = "Bob";
${ $list[0] }{LAST_NAME} = "Smith";
${ $list[0] }{PHONE_NUMBER} = "555-1234";
That's easy to read...
Fortunately, Perl provides a bit of syntactic sweetener. This is the same:
$list[0]->{FIRST_NAME} = "Bob";
$list[0]->{LAST_NAME} = "Smith";
$list[0]->{PHONE_NUMBER} = "555-1234";
The ->
operator points to the dereference you're doing.
Also, in certain circumstances, I don't need the {...}
curly braces. Think of it like math operations where there's an order of precedence:
(3 x 4) + (5 x 8)
is the same as:
3 x 4 + 5 x 8
One, I specify the order of operation, and the other I don't:
The original adding names into a hash reference stored in a list:
${ $list[0] }{FIRST_NAME} = "Bob";
${ $list[0] }{LAST_NAME} = "Smith";
${ $list[0] }{PHONE_NUMBER} = "555-1234";
Can be rewritten as:
$list[0]{FIRST_NAME} = "Bob";
$list[0]{LAST_NAME} = "Smith";
$list[0]{PHONE_NUMBER} = "555-1234";
(And I didn't have to do push @list, {};
first. I just wanted to emphasize that this was a reference to a hash.
Thus:
$trades{$id}
Is a reference to an array of data.
Think of it as this way:
my @list = qw(a bunch of data);
$trades{$id} = \@list;
And to dereference that reference to a list, I do this:
@{trades{$id}}
See Mark's Short Tutorial About References.
$summary{$sym}{$type}
is the same as$summary{$sym}->{$type}
– doubleDown Jun 13 '13 at 14:14print %summary;
before and after the line with the+=
. – ott-- Jun 13 '13 at 14:16sym1ARRAY(0xC0FFEE123)sym2ARRAY(0xDEADBEEF)
etc. Betteruse Data::Dumper; ...; print Dumper \%summary
oruse Data::Dump; ...; dd \%summary
to view nested data structures. – amon Jun 13 '13 at 14:19perl -e '%coins = ("Quarter", 25, "Dime", 10, "Nickel", 5); print %coins;'
givesNickel5Dime10Quarter25
. – ott-- Jun 13 '13 at 14:31