块变量范围的Ruby方法?

时间:2014-03-20 16:01:47

标签: ruby

我很好奇是否有可能将一个块传递给一个可以操作该方法的局部变量的方法。我有一个net / ssh帮助方法,我希望有一个可选的期望块:

def ssh_exec!(session,cmd,override=false, &block)
  stdout_data = ""
  stderr_data = ""
  exit_code = ""
  exit_signal = ""
  session.open_channel do |channel|
    channel.request_pty do |c, success|
      if success
        c.exec(cmd) do |ch, success|
          channel.on_data do |ch,data|
            stdout_data+=data
            yield if block_given?
          end
        end

        # irrelevant code omitted ...
      end
    end
  end
  [stdout_data, stderr_data, exit_code, exit_signal]
end

block = Proc.new {
  if data.inspect.include? "Proceed?"
    ch.send_data("Y\n")
  end
}

begin
  ssh_config = "/root/git/agil_system_test/test/distributed/ruby/conf/ssh.conf"
  ssh_user = "ec2-user"
  result = []
  Net::SSH.start('some_ssh_alias', ssh_user, :config => ssh_config) do |session|
    result = ssh_exec!(session,command,false, &block)
    # ...
  end
end

在这里,我最终得到错误: helper.rb:75:in block in <main>': undefined local variable or method data'for main:Object(NameError)

所以我认为这是一个范围问题。我正在尝试做什么?

1 个答案:

答案 0 :(得分:2)

是的,但是您需要将变量传递到块中:

channel.on_data do |ch,data|
  stdout_data+=data
  yield(ch, data) if block_given?
end

你的街区需要接受数据:

block = Proc.new do |ch, data|
  puts "Yo I'm in the block"
  puts data.inspect
  if data.inspect.include? "Proceed?"
    puts "here"
    ch.send_data("Y\n")
  end
end

proc的范围是声明它的位置,而不是它被调用的位置。

例如......

def my_method1
  local = "inside"
  block = Proc.new { puts local }
  block.call
end

my_method1 # writes "inside"


def my_method2(&block)
  local = "inside"
  block.call
end

local = "outside"
block = Proc.new { puts local }
my_method2(&block) # writes "outside"