2010-09-25 5 views
4

J'ai une boucle où j'exécute une série de commandes sur une machine distante:Ruby, Comment puis-je accéder à des variables locales en dehors du do - boucle d'extrémité


    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 

je veux accéder # {flux} et les données en dehors de la boucle do-end

J'apprécierais toute aide. Merci,

Salut Jörg,

Je mis en œuvre vos suggestions, mais maintenant je reçois l'erreur:


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 
+0

Désolé, c'est la nouvelle syntaxe littérale Ruby 1.9 'Hash' pour' Hash'es avec les clés 'Symbol'. Il suffit de remplacer tous les 'foo: bar' avec': foo => bar'. I.e .: 'communicateur = {: ch => ch,: flux => flux,: données => données}'. –

Répondre

19

Vous ne pouvez pas. Les variables locales sont locales à leur portée. C'est pourquoi ils sont appelés variables locales.

Vous pouvez toutefois utiliser une variable d'un champ extérieur:

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: il y avait plusieurs bugs dans votre code, qui l'aurait empêché de travailler de toute façon quel que soit votre problème avec la variable la portée, car vous avez utilisé une syntaxe incorrecte pour déréférencer les variables locales: la syntaxe pour déréférencer une variable est simplement le nom de la variable, par ex. foo, et non #{foo} (c'est simplement une erreur de syntaxe).

En outre, il y a d'autres améliorations:

  • mise en forme: la norme pour l'indentation Ruby est 2 places, pas 26
  • mise en forme: la norme pour l'indentation Ruby est 2 places : 0
  • formatage: généralement, les arguments de bloc sont séparés du mot-clé do avec un espace
  • clause garde: si vous envelopper tout le corps d'un bloc ou d'une méthode dans un conditionnel, vous pouvez simplement le remplacer par un garde un début du bloc qui saute le bloc entier si la condition est vraie
  • interpolation de chaîne: l'ajout de chaînes avec + est inhabituel dans Ruby; si vous devez concaténer des chaînes, vous le faites habituellement avec <<, mais plus souvent qu'autrement, l'interpolation de chaîne est préférée
  • plusieurs arguments à puts: si vous passez plusieurs arguments à puts, il imprimera tous sur une ligne séparée, vous n'avez pas besoin de l'appeler plusieurs fois
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 

Quelqu'un peut suggérer que vous faites référence à plusieurs variables de portée externe comme les paramètres de bloc , mais la portée des noms de paramètres de bloc a changé récemment dans Ruby et je suggérerais de le faire en toute sécurité et de le faire de cette façon. Je ne comprends pas ce qui se passe dans l'extrait, mais le motif de conception général est souvent utilisé pour générer des poignées vers des objets OS et des objets qui sont automatiquement arrêtés/fermés/etc une fois le bloc terminé, conservant ainsi le Ruby l'encapsuleur d'objet peut ne pas être utile.

+3

BTW: J'ai dû un peu de puzzle à propos de cette première ligne. Si vous voulez * vraiment * obtenir une bonne note, je pense que 'c, s, d = []' est moins obtus, mais je préférerais 'c = s = d = nil'. –

Questions connexes