Я не думаю, что для этого существует камень, но на самом деле это довольно просто - вы можете переназначить $ stdin на то, что обертывает (и восстанавливает) обычное устройство stdin!
Это у верхней части моей головы, и вы, вероятно, можно придумать что-то, что подходит для вашего варианта использования лучше, но это делает работу:
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
Здесь мы просто создать какой делегирует объект базовый поток STDIN для всего, а в случае #gets
записывает входные данные во время чтения. Вы можете позвонить LoggingInputStream.unhook
, чтобы восстановить $ stdin в канонический поток stdin и закрыть файл журнала.
Спасибо за то, что вы перешли в свой ответ :) Я могу в конечном итоге превратить это в драгоценный камень (опубликую здесь, если я это сделаю) - есть и другие связанные функции, которые я хотел бы инкапсулировать. – mralexlau