Ppeoc has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I am trying to initialize a hash which gets its keys from an array. What am I doing wrong with the following piece of code?
use strict; use warnings; use Data::Dumper; my $name = "Father" ; my @terms = qw(Mom Wife Son Daughter); my %fam_old = map{ $name => { $_,1 }} @terms; print Dumper \%fam_old,"\n";
Only the key Daughter gets initialized to 1. Please correct my error. I am looking for a hash like this
$VAR1 = { "Father" => { 'Son' => 1, 'Daughter' => 1, 'Wife' => 1, 'Mom' => 1 }; }

Replies are listed 'Best First'.
Re: Initializing hashes of hashes
by GrandFather (Saint) on Dec 19, 2015 at 21:48 UTC

    If I add strictures (use strict; use warnings;) to your sample code:

    use strict; use warnings; my $name = "Father" ; my @terms = qw(Mom Wife Son Daughter); my %fam_old = map{ $tool => { $_,1 }} @terms; print Dumper \%fam_old,"\n";

    it prints:

    Global symbol "$tool" requires explicit package name at ...\noname.pl +line 6. Execution of ...\noname.pl aborted due to compilation errors.

    Mybe you intended the hash assignment to be:

    my %fam_old = map{$_, 1} @terms;

    in which case the code prints:

    $VAR1 = { 'Son' => 1, 'Daughter' => 1, 'Wife' => 1, 'Mom' => 1 }; $VAR2 = ' ';
    Premature optimization is the root of all job security
Re: Initializing hashes of hashes
by Discipulus (Canon) on Dec 19, 2015 at 21:52 UTC
    the code is not complete, anyway you are telling to perl: fam_old is a list composed by the key tool that has Mom then Wife then Son then Daughter = 1.

    hoH are covered here

    Probably you want something like:
    $fam_old{'tool'} = {map{$_=>1}@terms}; $VAR1 = { 'tool' => { 'Son' => 1, 'Wife' => 1, 'Mom' => 1, 'Daughter' => 1 } };
    L*
    after the UPDATE just change tool with father!
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: updated question: Initializing hashes of hashes
by BillKSmith (Monsignor) on Dec 20, 2015 at 04:20 UTC
    use strict; use warnings; use Data::Dumper; my $name = "Father" ; my @terms = qw(Mom Wife Son Daughter); my %fam_old =( $name => { map{ $_=>1, } @terms} ); print Dumper \%fam_old;
    Output:
    $VAR1 = { 'Father' => { 'Son' => 1, 'Wife' => 1, 'Mom' => 1, 'Daughter' => 1 } };
    Bill
Re: Initializing hashes of hashes
by Anonymous Monk on Dec 19, 2015 at 22:43 UTC
    my $name = "Father" ; my @terms = qw(Mom Wife Son Daughter); my %fam_old = map{ $name => { $_,1 }} @terms;
    is equivalent to
    my $name = "Father" ; my %fam_old = ( $name => { 'Mom', 1 }, $name => { 'Wife', 1 }, $name => { 'Son', 1 }, $name => { 'Daugher', 1 }, );
    You only get 'Daugher' (associated with 'Father'), because your hash can have only one key 'Father'; so you get the last entry and not the rest of them.