1

I was curious if it was even possible to pass in a block into a method(s) that could manipulate that method's local variables. I have a net/ssh helper method that I would like to have an optional expect-like block:

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

Here I just end up getting the error: helper.rb:75:in block in <main>': undefined local variable or methoddata' for main:Object (NameError)

So I'm assuming it's an issue of scope. Is what I'm trying to do possible?

1 Answer 1

2

Yes it's possible, but you need to pass your variables into your block:

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

And your block needs to accept data:

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

The scope of a proc is where it was declared, not where it is invoked.

For example...

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"
Sign up to request clarification or add additional context in comments.

1 Comment

Ah magnificent. That was simple. Thanks for the fast response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.