我尝试访问此循环之外的对象/方法,以获取使用Ruby编码的简单HTTP服务器:
require 'socket' # Get sockets from stdlib
class Hello
def say_hi
"Hello, world!"
end
end
hi = Hello.new
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
Thread.start(server.accept) do |client|
client.puts(hi.say_hi)
client.close # Disconnect from the client
end
}
看起来请求只是挂起,因为" hi"及其" say_hi"方法不能在循环外访问。如何访问对象,模块和方法,以便将它们用于我的简单服务器?
答案 0 :(得分:2)
它按预期工作。当你调用server.accept时它会阻塞等待客户端连接。您可以通过启动程序并远程登录来确认这一点,例如:
telnet localhost 2000
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, world!
Connection closed by foreign host.
请注意,服务器以" Hello,world!"
回复答案 1 :(得分:0)
您提供的示例代码运行正常。我能够运行服务器,通过telnet localhost 2000
连接并接收" Hello,world!"连接关闭前的消息。
有时候某个区块无法访问其周围的本地范围。在您的示例中并非如此,但如果您在其他地方遇到此问题,则可以采取相应措施。
常量和全局变量在全局可见。您可以将Hello
实例变量分配给全局:$hi = Hello.new
,但大多数开发人员会告诉您使用全局变量是"坏"。您可以修改Hello
类,使其包含实例注册表:
require 'socket' # Get sockets from stdlib
class Hello
def initialize(name)
self.class.registry[name] = self
end
def say_hi
"Hello, world!"
end
def self.registry
@@registry ||= {}
end
end
Hello.new(:hi)
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
Thread.start(server.accept) do |client|
client.puts(Hello.registry[:hi].say_hi)
client.close # Disconnect from the client
end
}
还有其他方法可以克服范围问题,包括将hi
实例传递给Thread.start
,使用thread local variables等。很难在提供的代码已经有效的情况下建议具体的内容。