#!/usr/bin/perl
# Okay. I got really tired on never really understanding dereferencing in
# Perl. It's like having a brand new socket set in the tool box but you
# can't use it because you don't know how to get the open the case. I have
# done what I considered cheap-ass work-arounds in the past because of a
# lack of understanding. So I decided it was time to invest the two hours
# into it and once and for all figure this thing out.
#
# As I did it I made a crib sheet. Attached is that sheet. I did not do
# refs of refs to arrays of array refs, but change {key} to [0] in the
# last example and you have it. If someone is collecting this sort of
# thing on a web page miniathens would be a good choice for future
# reference (get it? "reference").
# My it lead you to reference heaven
# Mike Stute
# It's the damn syntax that will kill you
use strict;
# Deferencing Demystified (yeah right)
my @ary=("This","is","an","array");
my %hash=( language=>'Perl refs',
action=>'make',
possesive=>'heads',
verb=>'hurt');
my %other=(another=>'hash',
hash=>'definition');
# An array of hash refs
my @recs;
$recs[0]=\%hash;
$recs[1]=\%other;
my $aryref=\@ary;
my $hashref=\%hash;
# And Mr Nasty - a reference to an array of hash references
my $refref=\@recs;
#Many ways to dereference
print "Element 0 of \@ary is $$aryref[0] Better: $aryref->[0]\n";
print "Last of element of \@ary is $#{$aryref} \n";
#Now hashes
print "Entry 'action' of \%hash is $$hashref{action} Better:$hashref->{action}\n";
foreach my $key (keys %hash) {
print "Key $key\n";
}
print "------------------------------\n";
foreach my $val (values %hash) {
print "Val $val\n";
}
print "------------------------------\n";
foreach my $key (keys %hash) {
print "Key $key = $hash{$key}\n";
}
print "------------------------------\n";
print "Number of keys/total entries in \%hash = " . %hash ."\n";
print "------------------------------\n";
# Now with the reference
foreach my $key (keys %{$hashref}) {
print "Key $key\n";
}
print "------------------------------\n";
foreach my $val (values %{$hashref}) {
print "val $val\n";
}
print "------------------------------\n";
foreach my $key (keys %{$hashref}) {
print "Key $key = $hashref->{$key}\n";
}
print "------------------------------\n";
print "Number of keys/total entries in \$hashref = " . %{$hashref} ."\n";
# Now arrays of hashes
print "------------------------------\n";
print "Last entry in \@recs is $#recs\n";
# Print out the keys
print "------------------------------\n";
print "Recs[0] action = $recs[0]->{'action'}\n";
print "Recs[1] hash = $recs[1]->{'hash'}\n";
print "------------------------------\n";
# Go through them
foreach my $ref (@recs) {
foreach my $key (keys %{$ref}) {
print "key $key = $ref->{$key}\n";
}
}
print "------------------------------\n";
# Maybe recs is big and you don't have enough memory for the foreach
for(my $i=0;$i<$#recs+1;$i++) {
foreach my $key (keys %{$recs[$i]}) {
print "Key $key = $recs[$i]->{$key}\n";
}
}
print "------------------------------\n";
# Maybe recs is big and maybe the hash it contains is big too
# foreach is memory hungry since the second arg expands to the whole list all at one
# This method is very memory efficient
for(my $i=0;$i<$#recs+1;$i++) {
while ( my($key, $value) = each %{$recs[$i]}) {
print "Key $key = $value\n";
}
}
print "------------------------------\n";
# And now the mother of all ref storms the ref to an array of refs to hash
# Something I want to return from functions all the time
# With foreach
foreach my $href (@{$refref}) {
foreach my $key (keys %{$refref->[0]}) {
print "Key = $key = $$refref[0]->{$key} Better: Key = $key = $refref->[0]->{$key}\n";
}
}
print "------------------------------\n";
# With whiles
for(my $i=0;$i<$#{$refref}+1;$i++) {
while ( my($key, $value) = each %{$refref->[$i]}) {
print "Key $key = $value\n";
}
}
print "------------------------------\n";
print "Last entry in in recs: $#{$refref}\n";
print "Number of keys/total entries in \$refref hash 1 = " . %{$refref->[0]} ."\n";
# Now don't I look smart.