我目前正面临着这个问题,我似乎无法找到错误,但我认为这与Ruby块范围规则有关。我在这里阅读了不少帖子,但它们似乎与我遇到的问题不太相似(或者我可能太愚蠢而无法看到它)。我有一个Server对象,目前只有两个实例变量(主机名和操作系统)定义了setter / getters。
问题是我在读取ssh通道数据的块中间定义了一个Server对象的OS。我知道通道具有正确的数据,因为当我运行脚本时,它正确打印出“puts local OS”行,但是当它到达ch.exec块的末尾时,Server.getOS已经变回nil。
有什么想法吗?
备注&码: “hosts”是Server对象的数组。
hosts.each do |server|
begin
Net::SSH.start(server.getHostname, user , :password => password , :port=> port) do |ssh|
channel = ssh.open_channel do |ch|
ch.exec "uname" do |chan, success|
raise "could not execute uname command" unless success
chan.on_data do |c, data|
server.setOS = data
puts "local OS: #{server.getOS}"
# server.getOS = "AIX" here
end
chan.on_extended_data do |c, type, data|
puts data
end
end
puts "OS: #{server.getOS} -- hostname: #{server.getHostname}"
# server.getOS = "" here..
..然后从那里开始基于server.getOS开始处理,但server.getOS是nil。
答案 0 :(得分:0)
目前尚不清楚这里发生了什么,但可能的候选人没有确定范围,因为这会引发其他类型的错误,但是操作的顺序。如果这是异步操作,则可以在代码中exec
进一步调用之后执行puts
块。
请记住,Ruby中定义的块可以在任何时间点执行零次或多次。无法保证它们会立即执行,并且在进行异步操作时,预计它们将至少延迟一小段时间。
作为一个注释,使用getX
和setX
违背了Ruby的内容,其中x
和x=
是约定使用的方法。 Ruby中带有=
的方法名称被认为是mutator。