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

I'm playing aroudn with IO::Socket and IO::Select. One problem I've encounted is that IO::Select will return a list of socket connections (filehandles), but you will not know which socket is which.

Is it possible to use these as hash keys? For example:

@readable_handles=$selectobj->can_read(0.1); foreach my $socket (@readable_handles) { $sockethash{$socket}->{readable}=1; } # other places in the program can identify which # connection is being discussed by using the connection # handle as a hash key
(I've tried it, and -w and use strict don't complain, but my script isn't working overall...I can't tell if this is due to my lack of sockets comprehension, or this trick.)

If this doesn't work, is there an easy way to identify what socket you are dealing with?

Replies are listed 'Best First'.
Re: Sockets/filehandles as hash key?
by lhoward (Vicar) on Sep 11, 2000 at 18:23 UTC
    Have you considered using Tie::RefHash? Since the socket handles are refrences and you can't use refrences as hash keys without some special magic first....
    use Tie::RefHash; my %sockethash; tie %sockethash, 'Tie::RefHash'; ... @readable_handles=$selectobj->can_read(0.1); foreach my $socket (@readable_handles) { $sockethash{$socket}->{readable}=1; } etc...
      This looks to be exactly what I was missing. Thanks!
Re: Sockets/filehandles as hash key?
by merlyn (Sage) on Sep 11, 2000 at 18:28 UTC
    The code that I have used just inverts the problem. Here's a snippet:
    for my $ready (IO::Select->new(map $_->[1], values %kids)->can_r +ead(1)) { my ($kid) = grep $kids{$_}[1] == $ready, keys %kids; ## ... use $kids{$kid}[0], $kids{$kid}[2] etc. }
    Here, I'm storing the data in %kids where the key is some identifier (actually, the kid's PID) and a bunch of correlated values as an array(ref). One of those values (at index 1) is the handle to watch for reading. I construct the IO::Select on the fly, and when it returns one or more $ready values, I simply perform == to see which one of those handles it originally was, which gives me all the other correlated data as well.

    -- Randal L. Schwartz, Perl hacker

Re: Sockets/filehandles as hash key?
by lhoward (Vicar) on Sep 11, 2000 at 18:23 UTC
    Have you considered using Tie::RefHash? Since the socket handles are refrences and you can't use refrences as hash keys without some special magic first....
    use Tie::RefHash; my %sockethash; tie %sockethash, 'Tie::RefHash'; ... @readable_handles=$selectobj->can_read(0.1); foreach my $socket (@readable_handles) { $sockethash{$socket}->{readable}=1; } etc...
RE: Sockets/filehandles as hash key?
by Fastolfe (Vicar) on Sep 12, 2000 at 01:11 UTC
    Yes, you can, but one caveat: I think they lose their "magic" when they become hash keys, but if you try to assign them to a hash key, they all become simple strings that would work fine. You can't, as far as I know, take the result of (keys(%hash))[0] and print to it, because it's no longer a socket, but a string.

    If all you're doing is storing information about your sockets, though, I think it should work fine as a hash key. Again, just don't try to use the keys of your hash themselves as if they were objects/sockets.