⛳
[Bug #21280] StringIO#set_encoding でチルド文字列の警告が出てしまうチケット
[Bug #21280] StringIO#set_encoding warns when backed by chilled string literal
-
StringIO#set_encoding
では以下のような挙動になっています- 元の文字列が
frozen
でない場合はエンコーディングを変更する - 元の文字列が
frozen
されている場合はエンコーディングを変更しない
- 元の文字列が
require "stringio"
str = "hoge"
pp str.encoding # => #<Encoding:UTF-8>
# これはエンコーディングが変更される
StringIO.new(str).set_encoding('binary')
pp str.encoding # => #<Encoding:BINARY (ASCII-8BIT)>
# これはエンコーディングが変更されない
StringIO.new(str.freeze).set_encoding('UTF-8')
pp str.encoding # => #<Encoding:BINARY (ASCII-8BIT)>
- これを踏まえた上で Ruby 3.4 では
StringIO#set_encoding
時にチルド文字列に対して警告が出力されます
Warning[:deprecated] = true
require "stringio"
# warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
StringIO.new("hoge").set_encoding('binary')
- このチケットではこの警告が出力されるのは適切でないのではないか、という内容です
- 適切でない理由としては『件の警告が出力されるのは『文字列リテラルが frozen になった場合に壊れるケース』である』という話みたいですね
- それが今回のケースでは適切でない、という話みたい
- その上で『
StringIO#set_encoding
では元の文字列のエンコーディングを変更しない』という対処をするのが最初の話だったみたいです - ただ、『
StringIO#set_encoding
では元の文字列のエンコーディングを変更する必要がある』という話もあるみたいでそのあたりで議論しているみたいですね- https://github.com/ruby/stringio/pull/128#issuecomment-2818362875
- 議論の内容が『
StringIO#set_encoding
でエンコーディングを変えないようにする』と『警告を出す必要があるかどうか』の2つの話があるのでちょっとややこしい
- 最終的には『
StringIO#set_encoding
の挙動は変えずに警告のみ削除する』という対応になったみたいですね
Warning[:deprecated] = true
require "stringio"
StringIO.new("hoge").set_encoding('binary')
# Ruby 3.4 => warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
# Ruby 3.5 => no warning
- なんですが現時点だと Ruby 3.5 では
StringIO#set_encoding
で『元の文字列のエンコーディングを変更しない』ようになっているんですよねー
pp RUBY_DESCRIPTION
# => "ruby 3.5.0dev (2025-06-26T04:28:24Z master 5e9be99ef5) +PRISM [x86_64-linux]"
require "stringio"
str = "hoge"
StringIO.new(str).set_encoding('binary')
pp str.encoding
# Ruby 3.4 => #<Encoding:BINARY (ASCII-8BIT)>
# Ruby 3.5 => #<Encoding:UTF-8>
- これが意図する変更なのかそうでないのかはよくわかってない
Discussion