#!/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.