2009-02-23 20 views
1

我想在STDIN上使用select和在Ruby中使用TCP套接字,但由于某些原因,从select返回的值似乎永远不匹配其中的一个选项;它看起来像是被返回的套接字,但它不匹配使用==(或等于?)。谁能告诉我为什么从select返回的结果与我传入的对象不匹配,以及我应该在这里做些什么改变?为什么Ruby的select没有返回套接字?

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 

这里就是我得到的,当我运行此:

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

我在Mac OS X上运行的Ruby版本1.8.6

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

回答

7

select返回的Array的第一个元素是已准备好的IO对象的Array。所以你应该比较STDIN和服务器的结果[0] [0]。或者更好的检查一下,如果插座是在结果数组中

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

是的,就是这样。我想我错过了结果是一个数组数组;令人困惑的是,在我的调试语句中,数组的打印方式与单个套接字完全相同。 我结束了循环遍历结果[0]中的元素而不是使用include?,但你的回答让我开始了。谢谢! – 2009-02-23 15:57:24

0

你得到相同的结果如果你使用.equal?或.eql?

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

==子类可重写,但.equal?不应该是。这里的主要问题实际上是为什么当通过==比较自身时,同一个对象返回false。您可能需要查看TCPSocket类的源代码或文档。

+0

与.equal相同的结果?如果我尝试打印每个对象的__id__,它们是不同的: puts“IDs:results [0]:#{results [0] .__ id__},server:#{server .__ id__}” 给我:` ID:results [0]:1695840,server:1695990` – 2009-02-23 06:12:29

相关问题