2009-02-23 5 views
1

J'essaie d'utiliser select sur STDIN et un socket TCP dans Ruby, mais pour une raison quelconque, la valeur retournée par select ne semble jamais correspondre à l'un des choix; il semble que c'est le socket qui est retourné, mais il ne correspond pas en utilisant == (ou égal?). Quelqu'un peut-il me dire pourquoi le résultat renvoyé par select ne correspond pas aux objets que j'ai passés, et ce que je devrais faire différemment ici?Pourquoi la sélection de Ruby ne renvoie-t-elle pas le socket?

server = TCPSocket::new("irc.freenode.net", 7000) 
server.puts "NICK MyBot" 
server.puts "USER #{ENV['USER']} 0 * :My Bot" 

# <snip definitions> 

while (!$done) 
    results = select([server, STDIN], nil, nil) 
    if results[0] == STDIN 
    puts "Reading from STDIN" 
    execute_command 
    elsif results[0] == server 
    puts "Reading from server" 
    receive_data 
    else 
    puts "Something's wrong... results[0]: #{results[0]}, server: #{server}" 
    puts "IDs: results[0]: #{results[0].__id__}, server: #{server.__id__}" 
    exit 1 
    end 
end 

Voici ce que je reçois quand je lance ceci:

Something's wrong... results[0]: #<TCPSocket:0x33c390>, server: #<TCPSocket:0x33c390> 
IDs: results[0]: 1695840, server: 1695990

J'exécute la version Ruby 1.8.6 sur Mac OS X.

$ ruby --version 
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] 
$ which ruby 
/usr/bin/ruby

Répondre

7

Le premier élément du tableau renvoyé par select est un tableau des objets IO prêts. Vous devriez donc comparer le STDIN et le serveur aux résultats [0] [0]. Ou mieux vérifier, si le socket est dans les résultats Array

... 
if results[0].include? STDIN 
    ... 
elsif results[0].include? server 
... 
... 
+0

Oui, c'est ça. Je suppose que j'ai manqué que les résultats étaient un tableau de tableaux; et confusingly, le tableau imprimé exactement le même que le socket unique dans mon instruction de débogage. J'ai fini par faire une boucle sur les éléments dans les résultats [0] au lieu d'utiliser include ?, mais votre réponse m'a permis de commencer. Merci! –

+0

Ah, intéressant. J'ai oublié que l'impression d'un tableau via "# {tableau}" imprime simplement les éléments. Les dangers du déboguage des instructions d'impression, je suppose. :) –

+1

Dans Ruby1.9 cela s'est amélioré et [1, 2, 3] .to_s donne "[1, 2, 3]" au lieu de "123". Avec 1.8 vous obtenez ce comportement en appelant Array # inspect. – jgre

0

obtenez-vous les mêmes résultats Si vous utilisez .equal? ou .eql?

http://ruby-doc.org/core/classes/Object.html#M000341

== peut être remplacée par des sous-classes, mais .equal? n'est pas censé être. La question principale ici est en fait pourquoi le même objet, comparé à lui-même via ==, renvoie false. Vous devrez peut-être extraire la source ou les documents de la classe TCPSocket.

+0

Mêmes résultats avec .equal? Si j'essaie d'imprimer le __id__ de chaque objet, ils sont différents: met "IDs: résultats [0]: # {results [0] .__ id__}, serveur: # {server .__ id__}" Me donne: ' ID: résultats [0]: 1695840, serveur: 1695990' –

Questions connexes