class Dex::UI::StdoutRouter::Capture

Attributes

stderr[R]
stdout[R]

Public Class Methods

new(with_frame_inset: true, &block) click to toggle source
# File lib/dex/ui/stdout_router.rb, line 85
def initialize(with_frame_inset: true, &block)
  @with_frame_inset = with_frame_inset
  @block = block
end
with_stdin_masked() { || ... } click to toggle source
# File lib/dex/ui/stdout_router.rb, line 64
def self.with_stdin_masked
  @m.synchronize do
    if @active_captures.zero?
      @saved_stdin = $stdin
      $stdin, w = IO.pipe
      $stdin.close
      w.close
    end
    @active_captures += 1
  end

  yield
ensure
  @m.synchronize do
    @active_captures -= 1
    if @active_captures.zero?
      $stdin = @saved_stdin
    end
  end
end

Public Instance Methods

run() click to toggle source
# File lib/dex/ui/stdout_router.rb, line 92
def run
  StdoutRouter.assert_enabled!

  out = StringIO.new
  err = StringIO.new

  prev_frame_inset = Thread.current[:no_dexui_frame_inset]
  prev_hook = Thread.current[:dexui_output_hook]

  self.class.with_stdin_masked do
    Thread.current[:no_dexui_frame_inset] = !@with_frame_inset
    Thread.current[:dexui_output_hook] = ->(data, stream) do
      case stream
      when :stdout then out.write(data)
      when :stderr then err.write(data)
      else raise
      end
      false # suppress writing to terminal
    end

    begin
      @block.call
    ensure
      @stdout = out.string
      @stderr = err.string
    end
  end
ensure
  Thread.current[:dexui_output_hook] = prev_hook
  Thread.current[:no_dexui_frame_inset] = prev_frame_inset
end