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

Dear Monks,

I'm using IO::Select in order to switch between different clients connected to the same server program. At first, I used a sample code to understand how IO::Select works. That code uses the select() method in order to find the clients that have produced some output, like this:

$read_set = new IO::Select(); # create handle set for reading $read_set->add($socket); # add the main socket to the set # Get a set of readable handles (blocks until at least one handle is r +eady) my ($rh_set) = IO::Select->select($read_set, undef, undef, 0);

Now, after reading the module's documentation, I'm trying to understand what's the difference between using can_read() and select(). Can the last line in the above extract be written as  my @rh_set = $read_set->can_read(); ?

I can see that one method is static whole the other is not, and that one returns references to arrays, while the second returns one array - but are there any differences in the results themselves? Is one of them somehow "better" to use than the other?

Thanks a lot!

Replies are listed 'Best First'.
Re: Difference between can_read() and select() in IO::Select
by balakrishnan (Monk) on Feb 25, 2009 at 15:31 UTC
      When you say <a href="http://www.perlmonks.org/?node_id=255590">IO::Select: select vs. can_read</a> you really mean [id://255590]. The former sends people to one of four hostnames through which PerlMonks is available, each with its own cookie domain. The latter will leave a monk logged in after following the link no matter which hostname they use.*

      See Markup in the Monastery (which is linked near every node input box) for more information on markup on PerlMonks.

Re: Difference between can_read() and select() in IO::Select
by zentara (Cardinal) on Feb 25, 2009 at 15:39 UTC
    From my perspective, the select object just holds some bits indicating the state of the connection(s). So your $read_set can add many sockets....a whole giant internal array of them. It can loop over them constantly to see which sockets are open, in a recv/send state, etc. There is also the accept condition, so you can monitor everytime someone wants to connect to the socket.

    . So you will see pseudo logic like:

    while( my $sel = $select->can_read ){ if($sel->accept){spawn a new connection maybe by forking/threading or addi +ng to the select array } if( $sel->is_connected){ #check for connection status if ($sel->can_write){ etc } } }
    the problem comes with making the select work in a bi-directional manner, usually a forking server and or client is used so the socket can both send and recv simultaneously. If both client and server are set to either send or recv, it locks up the socket.

    I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness
Re: Difference between can_read() and select() in IO::Select
by targetsmart (Curate) on Feb 25, 2009 at 16:42 UTC
    I have also had confusions like this in the earlier stages, but now if I have confusion I will just open the module code and understand it.
    For example, if I want to know what can_read is doing in IO::Select, I will just do this on my system
    my system details OS:Debian GNU/Linux 4.0 Kernel:2.6.18-4-686 GNU/Linux Perl: 5.8.8
    steps I will follow
    $ locate Select.pm /usr/lib/perl/5.8.8/IO/Select.pm /usr/share/perl/5.8.8/Pod/Select.pm /usr/share/perl5/Debconf/AutoSelect.pm /usr/share/perl5/Debconf/Element/Dialog/Select.pm /usr/share/perl5/Debconf/Element/Editor/Select.pm /usr/share/perl5/Debconf/Element/Gnome/Select.pm /usr/share/perl5/Debconf/Element/Kde/Select.pm /usr/share/perl5/Debconf/Element/Noninteractive/Select.pm /usr/share/perl5/Debconf/Element/Select.pm /usr/share/perl5/Debconf/Element/Teletype/Select.pm /usr/share/perl5/Debconf/Element/Web/Select.pm /usr/share/perl5/HTML/Widget/Element/Select.pm I will open the below module in vim editor $vim /usr/lib/perl/5.8.8/IO/Select.pm just search the pattern /b can_read I have got this sub can_read { my $vec = shift; my $timeout = shift; my $r = $vec->[VEC_BITS]; defined($r) && (select($r,undef,undef,$timeout) > 0) ? handles($vec, $r) : (); } after seeing this I will know what can_read can do. I have done this for lot of perl modules and I have learnt some effici +ent techniques in this process, I am still learning, this is just my +tips to you.

    Vivek
    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.

      If you don't mind using a pager instead of an editor, perldoc -m IO::Select is easier.

      Sometimes reading the actual code is more confusing.:-) So you are trying to understand Perl's select, and you get code using select on vec? Simplifies things for sure. !! :-)

      I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness
Re: Difference between can_read() and select() in IO::Select
by Anonymous Monk on Feb 25, 2009 at 15:29 UTC
    Can the last line in the above extract be written as my @rh_set = $read_set->can_read();?
    Yes.

    but are there any differences in the results themselves? Is one of them somehow "better" to use than the other?
    No difference in results.

      No, they're not the same.

      my ($rh_set) = IO::Select->select($read_set, undef, undef, 0);
      is actually equivalent to
      my @rh_set = $read_set->can_read(0);
      These are non-blocking.

      my @rh_set = $read_set->can_read();
      and
      my @rh_set = $read_set->can_read(undef);
      block just like
      my ($rh_set) = IO::Select->select($read_set, undef, undef);
      and
      my ($rh_set) = IO::Select->select($read_set, undef, undef, undef);

      To the OP, can_read is just a thin wrapper around IO::Select::select that saves you from specifying undefs and dealing with the more complex return value.