Diferencia entre $ stdout y STDOUT en Ruby


89

En Ruby, ¿cuál es la diferencia entre $stdout(precedido por un signo de dólar) y STDOUT(en mayúsculas)? Al realizar la redirección de salida, ¿cuál debería usarse y por qué? Lo mismo ocurre con $stderry STDERR.

Editar: Acabo de encontrar una pregunta relacionada .



@theTinMan Algo es un duplicado. Sin embargo, debe tenerse en cuenta que mientras que las diferencias entre $stdouty STDOUTvs $stdiny STDINson simétricas, las diferencias entre $stdouty $>vs $stdiny $<no lo son.
skalee

Respuestas:


108

$stdoutes una variable global que representa la salida estándar actual. STDOUTes una constante que representa la salida estándar y suele ser el valor predeterminado de $stdout.

Al STDOUTser una constante, no debe volver a definirla, sin embargo, puede volver a definirla $stdoutsin errores / advertencias (la redefinición STDOUTgenerará una advertencia). por ejemplo, puedes hacer:

$stdout = STDERR

Lo mismo ocurre $stderrySTDERR


Entonces, para responder la otra parte de su pregunta, use las variables globales para redirigir la salida, no las constantes. Solo tenga cuidado de volver a cambiarlo más adelante en su código, la redefinición de variables globales puede afectar otras partes de su aplicación.


3
En realidad, si desea redirigir la salida, probablemente debería usar $>la secuencia de salida predeterminada, no $stdout.
Jörg W Mittag

10
Acabo de encontrar un comentario sobre otra pregunta que dice $stdouty $>son alias, por lo que reasignar uno afectará al otro.
jrdioko

9
@jrdioko: Tienes razón. Aparentemente, no solo aprendo algo nuevo todos los días, también olvido algo todos los días :-)
Jörg W Mittag

2
Y leyendo más, parece que es mejor usar IO # reopen en lugar de una simple asignación.
jrdioko

@jrdioko ¿Por qué crees que es mejor usarlo IO#reopenen caso de $stdout? Estoy totalmente en desacuerdo con esta opinión. El $stdout.reopenmétodo muta su receptor y eso también afectará STDOUTsi no ha reasignado $stdoutantes. No están destinados a ser sinónimos, no es nada malo cuando tienen valores diferentes debido a la asignación, y al reabrir el STDOUTmensaje estás rompiendo su propósito.
skalee

5
  • STDOUT es una constante global, por lo que no debe cambiarse.
  • $stdout es una variable predefinida, por lo que se puede cambiar.

Si está utilizando el shell para realizar la redirección:

$ ruby test.rb > test.log

entonces no importa cuál use como descriptor de archivo para su secuencia de comandos se determina antes de que se ejecute su secuencia de comandos.

Sin embargo, si está intentando cambiar el descriptor de archivo para STDOUT del sistema operativo desde su script Ruby, por ejemplo, para enviar resultados a un conjunto rotativo de archivos de registro según el día actual de la semana, entonces querrá asegurarse de que usa $stdout.


5
"STDOUT es una constante global, por lo que no va a cambiar". Es una constante, que PUEDE cambiarse, pero se emitirá una advertencia. STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
el hombre de hojalata

Ahh sí, entonces debería decir "entonces no debería cambiarse". ¡Gracias!
shakerlxxv

5

Ambos $stdouty STDOUTtienen diferentes significados. La documentación de Ruby es bastante clara sobre este tema:

  • $stdout - La salida estándar actual.
  • STDOUT- La salida estándar. El valor predeterminado de $ stdout.

Cuando desea escribir en la salida estándar, en realidad se refiere a la salida estándar actual , por lo que debe escribir en $stdout.

STDOUTtampoco es inútil. Almacena el valor predeterminado de $stdout. Si alguna vez reasigna $stdout, puede restaurarlo al valor anterior con $stdout = STDOUT.

Además, hay una variable predefinida más:

  • $>- La salida predeterminada para imprimir, printf, que es la $stdoutpredeterminada.

Sin embargo, parece que en Ruby 2.3 simplemente se comporta como un alias de $stdout. La reasignación $stdoutcambia el valor de $>y viceversa.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.