Ruby,我如何访问do-end循环之外的局部变量

我有一个循环,我在远程机器上执行一系列命令:

ssh.exec('cd /vmfs/volumes/4c6d95d2-b1923d5d-4dd7-f4ce46baaadc/ghettoVCB; ./ghettoVCB.sh -f vms_to_backup -d dryrun') do|ch, stream, data| if #{stream} =~ /vmupgrade/ puts value_hosts + " is " + data puts #{stream} puts data end end 

我想访问#{stream}和do-end循环之外的数据

我将不胜感激任何帮助。 谢谢,

嗨Jörg,

我实施了你的建议,但现在我收到了错误:

 WrapperghettoVCB.rb:49: odd number list for Hash communicator = {ch: ch, stream: stream, data: data} ^ WrapperghettoVCB.rb:49: syntax error, unexpected ':', expecting '}' communicator = {ch: ch, stream: stream, data: data} ^ WrapperghettoVCB.rb:49: syntax error, unexpected ':', expecting '=' communicator = {ch: ch, stream: stream, data: data} ^ WrapperghettoVCB.rb:49: syntax error, unexpected ':', expecting '=' communicator = {ch: ch, stream: stream, data: data} ^ WrapperghettoVCB.rb:76: syntax error, unexpected kELSE, expecting kEND WrapperghettoVCB.rb:80: syntax error, unexpected '}', expecting kEND 

你不能。 局部变量是其范围的本地变量。 这就是为什么它们被称为局部变量

但是,您可以使用外部作用域中的变量:

 communicator = nil ssh.exec('...') do |ch, stream, data| break unless stream =~ /vmupgrade/ puts "#{value_hosts} is #{data}", stream, data communicator = {ch: ch, stream: stream, data: data} end puts communicator 

顺便说一下:你的代码中有几个错误,无论你的变量作用域有什么问题,它都会阻止它工作,因为你使用了错误的语法来解除引用局部变量:取消引用变量的语法只是变量的名称,例如foo ,而不是#{foo} (这只是一个语法错误)。

此外,还有一些其他改进:

  • 格式化 :Ruby中缩进的标准是2个空格,而不是26个
  • 格式化 :Ruby中缩进的标准是2个空格,而不是0
  • 格式化 :通常,块参数与do关键字用空格分隔
  • guard子句 :如果你将一个块或方法的整个主体包装在一个条件中,你可以用一个保护替换它,如果条件为真,则跳过整个块的块的开头
  • 字符串插值 :将字符串与+一起添加在Ruby中是不常见的; 如果您需要连接字符串,通常使用<< ,但通常情况下,首选字符串插值
  • puts多个参数 :如果你将多个参数传递给puts ,它将在一个单独的行上打印所有这些参数,你不需要多次调用它
 c, s, d = [nil] * 3 str = '...' ssh.exec str do |ch, stream, data| c, s, d = ch, stream, data if #{stream} =~ /vmupgrade/ puts value_hosts + " is " + data puts #{stream} puts data end end 

有人可能会建议您只引用外部作用域变量作为块参数,但最近在Ruby中更改了块参数名称的作用域,我建议将其安全地播放并以这种方式进行。

我不明白代码片段中发生了什么,但是一般的设计模式通常用于产生操作系统对象的句柄以及在块完成后自动关闭/关闭/等的事情,因此保留Ruby对象包装器可能不会很有用。