代码之家  ›  专栏  ›  技术社区  ›  kamal

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

  •  5
  • kamal  · 技术社区  · 14 年前

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

    
       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
    

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

    谢谢,

    你好,Jrg,

    我执行了你的建议,但现在我得到了一个错误:

    
    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 回复  |  直到 14 年前
        1
  •  25
  •   Jörg W Mittag    14 年前

    你不能。局部变量是它们作用域的局部变量。这就是为什么他们被称为 .

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

    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} (这只是一个语法错误)。

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

    • 格式化
    • 格式化
    • :通常,块参数与 do 带空格的关键字
    • 保护条款 整个的 条件中的块或方法的主体,如果条件为真,您可以用块的开头的一个保护来替换它,该保护跳过整个块
    • :将字符串与 + 在红宝石中是不寻常的; 如果 << ,但通常情况下,首选字符串插值
    • puts :如果将多个参数传递给 ,它将在单独的一行中打印所有内容,您不需要多次调用它
        2
  •  5
  •   DigitalRoss    14 年前
    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对象包装器可能没有用处。