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

When I create a hash reference and then try to add values to undefined keys, can I add a different value to key1 and key2 at the same time?

Something like this, except it doesn't work:

$hashref->{"key1"} = "value1", {"key2"} = "value2";

This seems like it should be simple and if the answer is in perlreftut or perldsc (or anywhere else) please give me a big clue because the many attempts I've made just aren't working.

I don't really have a burning need, just trying to learn about references and hashes.
I can only add the values one at a time, as my example below demonstrates

use strict; use warnings; my %employees= ( "key1" => undef, "key2" => undef, "key3" => undef, ); my $hashref = \%employees; $hashref->{"key1"} = "value1"; $hashref->{"key2"} = "value2"; $hashref->{"key3"} = "value3"; print %$hashref,"\n";

Replies are listed 'Best First'.
Re: Assigning values to undef hash reference keys two or more at a time
by GrandFather (Saint) on Oct 23, 2008 at 00:37 UTC

    Here are a couple of techniques you can use:

    my %employees = map {$_ => undef} qw(key1 key2 key3); @employees{qw(key1 key2 key3)} = undef;

    Perl reduces RSI - it saves typing
Re: Assigning values to undef hash reference keys two or more at a time
by oko1 (Deacon) on Oct 23, 2008 at 01:13 UTC

    The thing you're looking for is called a hash slice.

    #!/usr/bin/perl -wl use strict; # Explicit lists of keys and values my %foo; # Note the '@' in front of the hash name! @foo{1..26} = "a".."z"; print $foo{10}; # Prints 'j' # You can use hash slices to return a list, too: print @foo{qw/8 5 12 12 15/}; # Prints 'hello' # You can use it to associate lists: my @employee_names = qw/Joe Jane Jim Jessie/; my @employee_ids = qw/1234 1235 1236 1237/; my %empl_lookup; @empl_lookup{@employee_ids} = @employee_names; # Now, you can look up employee names by ID: print $empl_lookup{1236}; # Hi there, Jim!

    It's a very useful method in Perl, and worth knowing well.

    Update: Whoops - I just noticed that I missed a couple of bytes in the question, and thus answered something other than what was asked.

    #!/usr/bin/perl -wl use strict; my (@a, @b, $foo); @a = qw/key1 key2/; @b = qw/val1 val2/; $foo = { map { $a[$_] => $b[$_] } 0..$#a }; print $foo->{key1}; # Prints 'val1'

    The above is a bit more like it. :)


    --
    "Language shapes the way we think, and determines what we can think about."
    -- B. L. Whorf
Re: Assigning values to undef hash reference keys two or more at a time
by AnomalousMonk (Archbishop) on Oct 23, 2008 at 03:13 UTC
    As mentioned above, take a look at hash Slices.
Re: Assigning values to undef hash reference keys two or more at a time
by AnomalousMonk (Archbishop) on Oct 23, 2008 at 19:31 UTC
    Try something like this:
    >perl -wMstrict -le "my %employees; my @values = ('value1', 'value2', 'value3'); @employees{ qw(key1 key2 key3) } = @values; print qq{ @{[ %employees ]} }; my $hashref = \%employees; @{ $hashref }{ qw(key1 key3) } = qw(foo bar); print qq{ @{[ %employees ]} }; " key2 value2 key1 value1 key3 value3 key2 value2 key1 foo key3 bar
    Note the critical syntax is @{ $hashref }{ qw(key1 key3) } = qw(foo bar);.
Re: Assigning values to undef hash reference keys two or more at a time
by gctaylor1 (Hermit) on Oct 23, 2008 at 18:18 UTC
    Now I understand which concept to use on the right side but I can't get my values assigned to the left side.

    perlreftut says "Whatever you want to do with a reference, Use Rule 1 tells you how to do it. You just write the Perl code that you would have written for doing the same thing to a regular array or hash, and then replace the array or hash name with {$reference} ."

    My traditional hash gets the values assigned to keys with this:

    my @values = ("value1", "value2", "value3"); @employees{qw(key1 key2 key3)} = @values;
    So I thought some form of this would work but I can't get it right.
    @{$hashref->{qw/key1 key2 key3/}} = @values; %{$hashref}->{qw/key1 key2 key3/} = @values;
    I've tried many more combinations, including moving the brackets all over the place. Is this even close? I need a bigger hint I guess.
      Rule 1, which you mention, provides the answer—except that maybe you have the wrong idea of what the ‘hash name’ is. Namely:
      @hash{ qw/key1 key2 key3/ }
      is the slice of the hash named 'hash' (not '%hash') corresponding to the indicated keys. If you want to slice a referent, just stick the (suitably bracketed) reference in place of the name:
      @{ $hashref }{ qw/key1 key2 key3/ }
      (as AnomalousMonk pointed out below).
Re: Assigning values to undef hash reference keys two or more at a time
by gctaylor1 (Hermit) on Oct 23, 2008 at 14:32 UTC
    All three of these responses provided something useful for me. Thanks to each of you.
Re: Assigning values to undef hash reference keys two or more at a time
by gctaylor1 (Hermit) on Oct 23, 2008 at 23:18 UTC
    I was thinking the infix operator needed to be used to dereference $hashref. Or more accurately, I guess I thought I could use it if I wanted and I chose to use it for consistency purposes. Plus it was just one thing I needed to remember instead of the various other ways to dereference and the docs I read suggested it might be easier to read.

    So the suggestion works by-the-way. I'm still trying to understand why infix -> didn't work.