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

Hello. I'm using IO::Select's can_read() function on many filehandles. The filehandles are actually contained in a hash (which is just a hash ref in an array actually). I add them to my IO::Select object, and then iterate over the ones that are readable:
my @readable = $s->can_read(1); foreach(@readable) { # Now $_ is the readable filehandles }
But what I need now, is to find the hash that that filehandle is located in. For instance: $hashes[5]->{child_fh} might be that one, or maybe $hashes[3]->{child_fh}. How do I find the hash that its in? (The key would always be 'child_fh', its just finding which element it is in @hashes)

Replies are listed 'Best First'.
Re: Getting at a hash from its values
by loikiolki (Novice) on Mar 01, 2006 at 05:19 UTC

    Here's one way of doing what you're asking for. Note that if you try to get an index for a child_fh value that does not exist, this method will die() on you (purposely).

    my @hashes = ( { child_fh => $obj1 }, { child_fh => $obj2 } ); my @readable = $s->can_read(1); for (@readable) { my $index = -1; while (++$index > -1) { last if ($hashes[$index]{child_fh} == $_); die("object not found in $hashes!\n") if ($index == $#hashes); ); # $index now contains your array index, '3' or '5' # from your example. print $hashes[$index]{child_fh}, "\n"; }
      The following two snippets are a bit easier to read:
      my @readable = $s->can_read(1); for my $fh (@readable) { my ($index) = grep { $hashes[$_]{child_fh} == $fh } 0..$#hashes; die("object not found in \$hashes!\n") if not defined $index; ... }

      and

      use List::Util qw( first ); my @readable = $s->can_read(1); for my $fh (@readable) { my $index = first { $hashes[$_]{child_fh} == $fh } 0..$#hashes; die("object not found in \$hashes!\n") if not defined $index; ... }
      Or if you don't need the index, just the object in @hashes:
      my @readable = $s->can_read(1); for my $fh (@readable) { my ($obj) = grep { $_->{child_fh} == $fh } @hashes or die("object not found in \$hashes!\n"); ... }

      and

      use List::Util qw( first ); my @readable = $s->can_read(1); for my $fh (@readable) { my $obj = first { $_->{child_fh} == $fh } @hashes or die("object not found in \$hashes!\n"); ... }