module Nuggets::IO::InteractMixin

Public Instance Methods

interact(input, output[, timeout[, maxlen]]) → anArray | nil click to toggle source

Interact with both ends of a pipe in a non-blocking manner.

input represents the sending end and is a mapping from the actual input IO (to send into the pipe) to the pipe's input handle (stdin). The input IO must support read_nonblock. If it's a StringIO it will be extended appropriately. If it's a String it will be converted to a StringIO.

output represents the receiving end and is a mapping from the pipe's output handle (stdout) to the designated output IO (to receive data from the pipe), and, optionally, from the pipe's error handle (stderr) to the designated error IO. The output and error IO must support << with a string argument. If either of them is a Proc it will be extended such that << delegates to call.

timeout, if given, will be passed to IO::select and nil is returned if the select call times out; in all other cases an empty array is returned.

maxlen is the chunk size for read_nonblock.

Examples:

require 'open3'

# simply prints 'input string' on STDOUT, ignores +stderr+
Open3.popen3('cat') { |stdin, stdout, stderr|
  IO.interact({ "input string\n" => stdin }, { stdout => STDOUT })
}

# prints lines you type in reverse order to a string
str = ''
Open3.popen3('tac') { |stdin, stdout, stderr|
  IO.interact({ STDIN => stdin }, { stdout => str })
}
puts str

# prints the IP adresses from /etc/hosts on STDOUT and their lengths
# on STDERR
cmd = %q{ruby -ne 'i = $_.split.first or next; warn i.length; puts i'}
Open3.popen3(cmd) { |stdin, stdout, stderr|
  File.open('/etc/hosts') { |f|
    IO.interact({ f => stdin }, { stdout => STDOUT, stderr => STDERR })
  }
}
# File lib/nuggets/io/interact_mixin.rb, line 78
def interact(input, output, timeout = nil, maxlen = nil)
  Interaction.new(input, output, timeout, maxlen).interact
end