dgo.a
dgo.a

Reputation: 2764

Is there a way to redirect STDERR in Crystal?

It would be convenient to redirect STDERR during tests. Is this possible in Crystal?

Upvotes: 1

Views: 465

Answers (2)

dgo.a
dgo.a

Reputation: 2764

Here is one possible way (inspired from https://github.com/mosop/stdio)

dup2 is included in Libc. dup has to be defined. You can then capture either STDOUT or STDERR:

lib LibC
  fun dup(oldfd : LibC::Int) : LibC::Int
end

def capture(origin)
  close_on_exec = origin.close_on_exec?
  begin
    o, i = IO.pipe
    dup = LibC.dup(origin.fd)
    origin.reopen(i)
    yield o
    LibC.dup2(dup, origin.fd)
    origin.close_on_exec = close_on_exec

  ensure
    o.close if o
    i.flush if i
    i.close if i
  end
end

STDERR.puts "a"
capture(STDERR) { |output|
  STDERR.puts "b\nc"
  puts output.gets.inspect
  puts output.gets.inspect
}
STDERR.puts "d"
capture(STDOUT) { |output| STDOUT.puts "this is ignored" }
puts "done"

Upvotes: 2

Oleh Prypin
Oleh Prypin

Reputation: 34116

There is no way of doing it with just the standard library, but there is an external library that does the low-level operation.

https://github.com/mosop/stdio
A small Crystal library for capturing standard I/O streams

Upvotes: 5

Related Questions