Ruby, как я могу получить доступ к локальным переменным вне цикла do - end - PullRequest
5 голосов
/ 25 сентября 2010

У меня есть цикл, в котором я выполняю серию команд на удаленной машине:


   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

Буду признателен за любую помощь.Спасибо,

Привет, Йорг,

Я реализовал ваши предложения, но теперь получаю сообщение об ошибке:


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 ]

21 голосов
/ 25 сентября 2010

Вы не можете. Локальные переменные являются локальными в своей области. Вот почему они называются локальными переменными .

Однако вы можете использовать переменную из внешней области видимости:

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 пробелом
  • элемент охраны : если вы оберните все тело блока или метода в условное выражение, вы можете просто заменить его на начало блока, которое пропускает весь блок, если условие истинно
  • интерполяция строк : добавление строк вместе с + необычно в Ruby; если вам нужно объединить строки, вы обычно делаете это с <<, но чаще всего предпочтительнее интерполяция строк
  • несколько аргументов puts: если вы передадите несколько аргументов puts, они будут напечатаны в отдельной строке, вам не нужно вызывать его несколько раз
5 голосов
/ 25 сентября 2010
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 Обертка может быть бесполезной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...