Array References and Hashes of Hashes in Perl

Here’s some Perl code showing how to pass arrays around and also how to use a hash of hashes instead. The Perl books I have, perldoc, and Google did not really tell me what I wanted to know to do this sort of stuff, so I wasted a lot of time messing around. I’m not sure why that was…. I guess them Perl folks have different habits or terminology or something. (Not that I have anything against that…. I wouldn’t be learning it if it wasn’t different, now would I?)

(Note the the threearrays subroutine is returning an array of references. The crazy subroutine is casting those references back into local variables that you can play with. You have to do similar stuff when you want to play with hashes like that, too. I haven’t yet picked up a less verbose approach for doing that sort of thing.)

Anyways, with these notes, you might be able to more quickly move from a quick-and-dirty Perl script style into a more functional approach in your Perl coding. Good luck.

#!/usr/bin/perl
$foo[0] = 1;	
$foo[1] = 4;	
$foo[2] = 9;	

@bar = makearray(1,8,27);

showme(@foo);
showme(@bar);

&crazy;
¬ascrazy;

sub makearray {
    my @array;
    foreach(0..2){
	@array[$_] = @_[$_];
    }			
    return @array;
}

sub showme {
    my (@array) = @_;
    foreach(0..2){
	print "$array[$_]\n";
    }	
}

sub threearrays {
    my @one, @two, @three;
    foreach(0..2){
	@one[$_] = ($_ + 1) * 1;
	@two[$_] = ($_ + 1) * 2;
	@three[$_] = ($_ + 1) * 3;
	#print "($one[$_], $two[$_], $three[$_])\n";
    }
    
    my @all;
    @all[0] = \@one;
    @all[1] = \@two;
    @all[2] = \@three;
    return @all;
}

sub crazy {
    my @x = &threearrays;
    my @a = @{$x[0]};
    my @b = @{$x[1]};
    my @c = @{$x[2]};
    showme(@a);
    showme(@b);
    showme(@c);
}

sub hashorama {
    my %hash, $a;
    foreach(0..2){
	$a = $_;
	foreach(0..2){
	    $hash{$a}{$_} = ($a + 1) * ($_ + 1);
	}	 
    }
    return %hash;		
}

sub notascrazy {
    my %hash = &hashorama;
    my $a;
    print "not as crazy\n";
    foreach(0..2){
	$a = $_;
	foreach(0..2){
	    print "$hash{$a}{$_}\n";
	}
    }	
}
Advertisements

One Response to “Array References and Hashes of Hashes in Perl”

  1. Eric TF Bat Says:

    This is unreadable for a reason — you’re not using Perl idioms. For a start, this is entirely wrong:

    sub foo {
    foreach (0..2) {
    # do something with @_[$_]
    }
    }

    That’s one way of getting each argument, but it’s not a good one. The better method is this way:

    sub foo {
    my ($x, $y, $z) = @_;
    # do something with $x, $y and $z, which are the parameter values
    }

    or, if you must iterate through all the args, this way:

    sub foo {
    my @args = @_;
    foreach my $i (0..2) {
    # do something with $args[$i]
    }
    }

    Notice I’m using $args[], not @args[]. They both refer to an array called @args, but the first returns each value and the second returns an array of each value. This difference can matter.

    Perl is a bit ugly, but it’s not as ugly as your examples! I recommend reading The Camel Book before you touch another line of Perl code, or you’re just making headaches for yourself and whoever has to maintain your code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: