Setting default_external affects STDIN encoding but default_internal does not
Changing Encoding.default_external changes STDIN.external_encoding, but changing Encoding.default_internal does not change STDIN.internal_encoding.
STDOUT and STDERR internal/external encodings are not changed in either case and are always nil.
Is this a bug? See the following IRB transcript:
1.9.3p286 :001 > Encoding.default_external
1.9.3p286 :002 > Encoding.default_internal
1.9.3p286 :003 > STDIN.external_encoding
1.9.3p286 :004 > STDIN.internal_encoding
1.9.3p286 :005 > Encoding.default_external = "euc-jp"
1.9.3p286 :006 > STDIN.external_encoding
1.9.3p286 :007 > STDIN.internal_encoding
1.9.3p286 :008 > Encoding.default_internal = "iso-8859-1"
1.9.3p286 :009 > STDIN.internal_encoding
#4 [ruby-core:49199] Updated by duerst (Martin Dürst) over 5 years ago
I'm not sure what the reason was for the current state, but I can easily
imagine a situation where stdin/stdout are the console and therefore in
one encoding, whereas the data a script is working on is all in another
#5 [ruby-core:49245] Updated by naruse (Yui NARUSE) over 5 years ago
brixen (Brian Ford) wrote:
Can someone please explain how the inconsistency with how the rest of IO instances would behave with transcoding is not a bug?
This is because IO object's internal property are set when it is created.
In this case, STDIN's internal property is not changed when default_external and default_internal are set.
And in this situation, STDIN.external_encoding returns current Encoding.default_external,
so it looks as if Encoding.default_external changes STDIN.
Following are detail
= IO's internal property
An IO object has two internal properties, extenc (external encoding) and intenc (internal encoding).
When extenc and intenc are explicitly given like open("foo.txt", "r:UTF-8:ISO-8859-1"),
extenc is UTF-8 and intenc is ISO-8859-1
When extenc and intenc are not given like open("foo.txt", "r") or STDIN without -E/-U,
extenc is nil and intenc is nil.
If extenc is not nil, returns extenc.
If extenc is nil, returns current Encoding.default_external.
This method is to know what encoding is set on io.read.
(this had to be always return extenc...)
Current inconsistency is derived from IO objects' internal state and settings for conversion.
The change will need add more internal property and breaking IO#external_encoding.
I couldn't design better one yet.