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

时间:2010-09-25 18:36:48

标签: ruby

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


   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

2 个答案:

答案 0 :(得分:21)

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

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

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
BTW:您的代码中存在多个错误,无论您的变量作用域存在问题,都会阻止它无论如何 ,因为您使用了错误的语法来取消引用局部变量:取消引用的语法变量只是变量的名称,例如foo,而非#{foo}(这只是语法错误)。

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

  • 格式化:Ruby中缩进的标准是2个空格,而不是26
  • 格式化:Ruby中缩进的标准是2个空格,而不是0
  • 格式化:通常,块参数与do关键字以空格分隔
  • guard子句:如果你将一个块或方法的整个主体包装在一个条件中,你可以用一个守护替换那个块的开头那个如果条件为真,则跳过整个块
  • 字符串插值:在Ruby中添加字符串和+是不常见的; 如果你需要连接字符串,你通常用<<来做,但通常情况下,首选字符串插值
  • puts 的多个参数:如果您将多个参数传递给puts,它会在一个单独的行上打印所有参数,您无需调用它多次

答案 1 :(得分:5)

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对象包装器可能没用。