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 .

jrdioko
fuente
posible duplicado de ¿Cuál es la diferencia entre STDIN y $ stdin en Ruby?
el hombre de hojalata
@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.

Brian
fuente
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.

shakerlxxv
fuente
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.

skalee
fuente