2015-02-25 1 views
0

Есть ли рубиновый камень, который автоматически регистрирует входные данные из $ stdin, сохраняя при этом нормальный поток выполнения для программы?Gem для захвата/воспроизведения входа stdin в ruby ​​

Я думал, что-то вроде:

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

Затем вы можете использовать этот файл позже повторить тот же вход. Существует ли камень с этой функциональностью?

ответ

1

Я не думаю, что для этого существует камень, но на самом деле это довольно просто - вы можете переназначить $ 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 и закрыть файл журнала.

+0

Спасибо за то, что вы перешли в свой ответ :) Я могу в конечном итоге превратить это в драгоценный камень (опубликую здесь, если я это сделаю) - есть и другие связанные функции, которые я хотел бы инкапсулировать. – mralexlau