ruby - tomar - como hacer una captura de pantalla en el celular
¿Cómo puedo capturar STDOUT en una cadena? (6)
puts "hi"
puts "bye"
Quiero almacenar el STDOUT del código hasta el momento (en este caso hi / nbye en una variable decir ''resultado'' e imprimirlo)
puts result
La razón por la que estoy haciendo esto es porque he integrado un código R en mi código Ruby, cuyo resultado se entrega al STDOUT a medida que se ejecuta el código R, pero no se puede acceder al resultado dentro del código para hacer algunas evaluaciones. Perdón si esto es confuso. Entonces la línea de "poner resultados" debería darme un saludo.
Redirigir salida estándar a un objeto StringIO
Sin duda puede redirigir salida estándar a una variable. Por ejemplo:
# Set up standard output as a StringIO object.
foo = StringIO.new
$stdout = foo
# Send some text to $stdout.
puts ''hi''
puts ''bye''
# Access the data written to standard output.
$stdout.string
# => "hi/nbye/n"
# Send your captured output to the original output stream.
STDOUT.puts $stdout.string
En la práctica, probablemente esta no sea una gran idea, pero al menos ahora sabes que es posible.
Credit to @ girasquid''s answer. Lo modifiqué a una sola versión de archivo:
def capture_output(string)
`echo #{string.inspect}`.chomp
end
# example usage
response_body = "https://x2F//x2Faccounts.google.com//x2Faccounts"
puts response_body #=> https:/x2F/x2Faccounts.google.com/x2Faccounts
capture_output(response_body) #=> https://accounts.google.com/accounts
El siguiente método es una útil herramienta de propósito general para capturar stdout y devolverlo como una cadena. (Utilizo esto con frecuencia en pruebas unitarias en las que quiero verificar algo impreso en stdout.) Tenga en cuenta especialmente el uso de la cláusula Ensure para restaurar $ stdout (y evitar el asombro):
def with_captured_stdout
old_stdout = $stdout
$stdout = StringIO.new
yield
$stdout.string
ensure
$stdout = old_stdout
end
Así por ejemplo:
>> str = with_captured_stdout { puts "hi"; puts "bye"}
=> "hi/nbye/n"
>> print str
hi
bye
=> nil
Para la mayoría de los propósitos prácticos, puede poner cualquier cosa en $stdout
que responda a write
, flush
, sync
, sync=
y tty?
.
En este ejemplo, uso una Queue modificada de stdlib.
class Captor < Queue
alias_method :write, :push
def method_missing(meth, *args)
false
end
def respond_to_missing?(*args)
true
end
end
stream = Captor.new
orig_stdout = $stdout
$stdout = stream
puts_thread = Thread.new do
loop do
puts Time.now
sleep 0.5
end
end
5.times do
STDOUT.print ">> #{stream.shift}"
end
puts_thread.kill
$stdout = orig_stdout
Necesita algo como esto si quiere actuar activamente sobre los datos y no solo mirarlos una vez que la tarea haya terminado. Usar StringIO o un archivo tendrá problemas con varios hilos que intenten sincronizar lecturas y escrituras simultáneamente.
Puedes hacer esto haciendo una llamada a tu guión R dentro de los palos de atrás, como este:
result = `./run-your-script`
puts result # will contain STDOUT from run-your-script
Para obtener más información sobre cómo ejecutar subprocesos en Ruby, consulte esta pregunta sobre desbordamiento de pila .
Si activesupport está disponible en su proyecto, puede hacer lo siguiente:
output = capture(:stdout) do
run_arbitrary_code
end
Puede encontrar más información sobre Kernel.capture
here