views:

8617

answers:

4

Up until recently, I've been storing multiple values into different hashes with the same keys as follows:

%boss = (
    "Allan"  => "George",
    "Bob"    => "George",
    "George" => "lisa" );

%status = (
    "Allan"  => "Contractor",
    "Bob"    => "Part-time",
    "George" => "Full-time" );

and then I can reference $boss("Bob") and $status("Bob") but this gets unwieldy if there's a lot of properties each key can have and I have to worry about keeping the hashes in sync.

Is there a better way for storing multiple values in a hash? I could store the values as

        "Bob" => "George:Part-time"

and then disassemble the strings with split, but there must be a more elegant way.

+19  A: 

This is the standard way, as per perldoc perldsc.

~> more test.pl
%chums = ( "Allan" => {"Boss" => "George", "Status" => "Contractor"},
           "Bob" => {"Boss" => "Peter", "Status" => "Part-time"} );

print $chums{"Allan"}{"Boss"}."\n";
print $chums{"Bob"}{"Boss"}."\n";
print $chums{"Bob"}{"Status"}."\n";
$chums{"Bob"}{"Wife"} = "Pam";
print $chums{"Bob"}{"Wife"}."\n";

~> perl test.pl
George
Peter
Part-time
Pam
Vinko Vrsalovic
That looks okay. I guess I can add another chum with $chums{"Greg"} = {"Boss" => "Lisa", "Status" => "Fired"} but how do I go about adding a wife to Bob? Would that be $chums{"Bob"}{"Wife"} = "Carol"?
paxdiablo
Also, why the "->". It seems to function without these.
paxdiablo
TIMTOWDI :), you can use it without them, and yes, your way to add a wife is correct
Vinko Vrsalovic
+3  A: 

Hashes can contain other hashes or arrays. If you want to refer to your properties by name, store them as a hash per key, otherwise store them as an array per key.

There is a reference for the syntax.

moonshadow
+2  A: 
my %employees = (
    "Allan" => { "Boss" => "George", "Status" => "Contractor" },
);

print $employees{"Allan"}{"Boss"}, "\n";
Swaroop C H
+14  A: 

Hashes of hashes is what you're explicitly asking for. There is a tutorial style piece of documentation part of the Perl documentation which covers this: Data Structure Cookbook But maybe you should consider going object-oriented. This is sort of the stereotypical example for object oriented programming tutorials.

How about something like this:

#!/usr/bin/perl
package Employee;
use Moose;
has 'name' => ( is => 'rw', isa => 'Str' );

# should really use a Status class
has 'status' => ( is => 'rw', isa => 'Str' );

has 'superior' => (
  is      => 'rw',
  isa     => 'Employee',
  default => undef,
);

###############
package main;
use strict;
use warnings;

my %employees; # maybe use a class for this, too

$employees{George} = Employee->new(
  name   => 'George',
  status => 'Boss',
);

$employees{Allan} = Employee->new(
  name     => 'Allan',
  status   => 'Contractor',
  superior => $employees{George},
);

print $employees{Allan}->superior->name, "\n";
tsee
This has the benefit that it can be enhanced in the future.
Brad Gilbert