1

I'm storing a hash references from a threads to a shared @stories variable, and then can't access them.

    my @stories : shared= ();

    sub blah {
    my %stories : shared=();
    <some code>
      if ($type=~/comment/) {
          $stories{"$id"}="$text";
          $stories{"$id"}{type}="$type";
          lock @stories;
          push @stories, \%stories;
      }  
    }

# @stories is a list of hash references which are shared from the threads;

           foreach my $story (@stories) {
                my %st=%{$story};
                print keys %st;        # <- printed "8462529653954"
                print Dumper %st;      # <- OK
                my $st_id = keys %st;
                print $st_id;          # <- printed "1"
                print $st{$st_id};     # <- printed "1/8"
           }

print keys %st works as expected but when i set in to a variable and print, it returns "1".

Could you please advice what I'm doing wrong. Thanks in advance.

  • 2
    What do you expect to happen? `$st_id = keys %st` is the same as `$st_id = scalar(keys %st)`, meaning set `$st_id` to the number of keys in the hash `%st`. – mob Nov 14 '13 at 17:39
  • I expect $st_id will be a key. i.e. 8462529653954. – Tigran Khachikyan Nov 14 '13 at 17:40
  • Are you aware that `my %st=%{$story}` is making a copy of the hash? Any change you make to `%st` are not reflected in the original hashref. – cjm Nov 14 '13 at 17:42
  • yes. At first I tried the same with $story, but when I sow the same thing I just tried this way :). I need to get values from the $story hash reference and then copy them to another hash. – Tigran Khachikyan Nov 14 '13 at 17:45
  • I expect that print $st_id; # will be 8462529653954 and print $st{$st_id}; # will be "some text" – Tigran Khachikyan Nov 14 '13 at 17:48

1 Answers1

3

In scalar context, keys %st returns the number of elements in the hash %st.

%st = ("8462529653954" => "foo");
$st_id = keys %st;

print keys %st;             #  "8462529653954"
print scalar(keys %st);     #  "1"
print $st_id;               #  "1"

To extract a single key out of %st, make an assignment from keys %st in list context.

my ($st_id) = keys %st;     #  like @x=keys %st; $st_id=$x[0]
print $st_id;               #  "8462529653954"
mob
  • 117,087
  • 18
  • 149
  • 283
  • That works, Thank you. But actually I don understand why keys %st is a list? – Tigran Khachikyan Nov 14 '13 at 17:57
  • @TigranKhachikyan, because a hash normally has more than 1 key. – cjm Nov 14 '13 at 17:58
  • 2
    And be aware that if `%st` has multiple keys, which one you get is undefined. You'll always get the same key until the hash is modified, at which point another key could become "first". – cjm Nov 14 '13 at 18:00