mralexlau
mralexlau

Reputation: 2003

Gem to capture/replay stdin input in ruby

Is there a ruby gem that automatically logs input from $stdin, while preserving normal execution flow for the program?

I was thinking something like:

def gets_with_logging
  input = gets_without_logging
  File.write('/path/to/file', input)
  return input
end
alias_method_chain :gets, :logging

Then you could use that file later on to replay the same input. Does a gem exist with this functionality?

Upvotes: 0

Views: 101

Answers (1)

Chris Heald
Chris Heald

Reputation: 62708

I don't think that a gem exists for this, but it's actually pretty easy - you can reassign $stdin to something that wraps (and restores) the usual stdin device!

This is off the top of my head, and you can probably come up with something that fits your use case better, but it does the job:

class LoggingInputStream
  def self.hook
    $stdin = new($stdin)
  end

  def self.unhook
    $stdin.finish if $stdin.is_a? LoggingInputStream
    $stdin = STDIN
  end

  def initialize(real_stdin)
    @real = real_stdin
    @log = File.open("log", "a")
  end

  def gets(*args)
    input = @real.gets(*args)
    log input
    input
  end

  def log(input)
    @log.puts input
    @log.flush
  end

  def finish
    @log.close
  end

  def method_missing(name, *args, &block)
    @real.send name, *args, &block
  end
end
LoggingInputStream.hook

Here we just create an object which delegates to the underlying STDIN stream for everything, and in the case of #gets, logs the input as it's read. You can call LoggingInputStream.unhook to restore $stdin to the canonical stdin stream and close the log file.

Upvotes: 1

Related Questions