From: "mame (Yusuke Endoh) via ruby-core" Date: 2025-05-09T03:28:58+00:00 Subject: [ruby-core:121924] [Ruby Bug#21280] StringIO#set_encoding warns when backed by chilled string literal Issue #21280 has been updated by mame (Yusuke Endoh). Discussed at the dev meeting. @matz said that he prefers not to issue warnings that could be false positives, even if they are true positives in many cases. The code `StringIO.new("").set_encoding('binary')` will work even in future as long as StringIO is used read-only. Therefore, this warning could be a false positive, and it would be nice to stop this warning in `StringIO#set_encoding`. In code that needs to be changed (i.e., the StringIO is used as read-write mode), it is expected that a warning will be finally issued by `StringIO#write` or something after a while, even if we don't issue the warning in `StringIO#set_encoding`. ---------------------------------------- Bug #21280: StringIO#set_encoding warns when backed by chilled string literal https://bugs.ruby-lang.org/issues/21280#change-113032 * Author: jeremyevans0 (Jeremy Evans) * Status: Open * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- `StringIO#set_encoding` changes the underlying string encoding if the string is not frozen, but does not change the underlying string encoding if the string is frozen. In Ruby 3.4, this results in a warning for chilled literal strings: ``` $ ruby34 -w -r stringio -e "StringIO.new('').set_encoding('binary')" -e:1: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information) ``` I believe Ruby should emit this warning only for cases that will break when string literals are frozen. This is not one of those cases, so Ruby should not emit the warning. To avoid emitting the warning, I think `StringIO#set_encoding` should not set the encoding on the underlying string for chilled literal strings. I submitted a pull request to avoid changing the encoding of the underlying string: https://github.com/ruby/stringio/pull/128 However, @rhenium said that he thought the encoding of the underlying string should still be changed, and the warning should be emitted (https://github.com/ruby/stringio/pull/128#issuecomment-2818362875). For some history, before Ruby 2.3, `StringIO#set_encoding` used to always set the encoding of the underlying string. This was changed in #11827, when the encoding was not set on the underlying string if the string was frozen (commit:3e1c01ae463a8c9d8bbe9050251a2538ddb0292f). In https://bugs.ruby-lang.org/issues/11827#note-3, @nurse wrote: > Away from the case and thinking ideal behavior, StringIO should be a view of given source string and set_encoding shouldn't change source encoding. > But I'm not sure that it is worth breaking the compatibility. I think this means that ideally, absent backwards compatibility issues, StringIO#set_encoding should never change the underlying string encoding. In https://bugs.ruby-lang.org/issues/11827#note-4, @shugo gave an example from @nobu that open-uri depends on the current behavior: ```ruby enc = Encoding::ASCII_8BIT unless enc if self.respond_to? :force_encoding self.force_encoding(enc) elsif self.respond_to? :string self.string.force_encoding(enc) else # Tempfile self.set_encoding enc end end ``` However, as `StringIO#string` is defined, this will call `self.string.force_encoding(enc)` and not `self.set_encoding enc`, so I'm not sure why a change to `String#set_encoding` would affect the behavior of this example. @rhenium pointed out that this issue affects `StringIO#binmode` and `StringIO#set_encoding_by_bom` as well as `StringIO#encoding`. How do we want to handle this case? Should this result in a warning (current behavior), or is it safe to avoid changing the encoding of the underlying string for chilled strings (as is done for frozen strings)? -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/