-
Notifications
You must be signed in to change notification settings - Fork 30
Do not issue warning when calling set_encoding if string is chilled #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
StringIO does not warn for unchilled unfrozen string or for frozen string, so it should not warn for chilled string.
Co-authored-by: Sutou Kouhei <[email protected]>
Doesn't this change the semantics of StringIO when used with what is (for now) not actually a frozen string? As I understand it currently if you're only reading the string the encoding is used to determine how to interpret the data but the encoding of the underlying string is not changed, but if you're writing then the encoding of the underlying string is changed, which will be important if you then try and use the string you've filled via the StringIO handle. With this change if you use StringIO to write to a constant, but non-frozen, string literal (which is entirely valid for now, if deprecated) then the encoding will be used to do the write but the resulting string will not have the right encoding. At the very least it sounds like it would be a semver major change? |
With this change, StringIO#set_encoding will no longer attempt to change the encoding of the underlying string for chilled strings. I don't consider that changing the semantics, because this StringIO behavior is not mentioned in the documentation, it is an implementation detail. As StringIO already does not do this for frozen strings, not doing it for chilled strings seems reasonable. After all, when Ruby changes literal strings from chilled by default to frozen by default, this will automatically happen anyway, so this just does so a little earlier to avoid the deprecation warning.
Note that writing to a StringIO backed by a chilled string is still deprecated with this commit. The only change is when you get the deprecation warning. Instead of getting it in require 'stringio'
Warning[:deprecated] = true
x = "\u1234"
s = StringIO.new(x)
p x.encoding
s.set_encoding("BINARY")
p x.encoding
p x.valid_encoding?
s << "\x89"
p x.valid_encoding? output:
If you only read and call You are correct that the encoding of the string becomes invalid. However, StringIO will modify strings in ways that result in invalid encodings even when it does change the encoding of the underlying string: require 'stringio'
Warning[:deprecated] = true
x = "\u1234".b
s = StringIO.new(x)
p x.encoding
s.set_encoding("UTF-8")
p x.encoding
p x.valid_encoding?
s << "\x89"
p x.valid_encoding? output:
If StringIO raised an error if asked to write a string with an invalid encoding, then I guess you could argue that. However, since it does not, and misuse of StringIO can result in invalid string encodings even in the case where it changes the encoding of the underlying string, this doesn't sound like a semver major change to me. |
@tomhughes Do you have any more opinions before we merge this? |
FWIW, The current behavior of
Since StringIO backed by a chilled string allows writing, my interpretation is that calling |
I'm no expert so I'm happy to defer to others - was just trying to make sure people had considered this and whether it was reasonable or would break people's expectations. |
StringIO does not warn for unchilled unfrozen string or for frozen string, so it should not warn for chilled string.