Skip to content

Conversation

@otegami
Copy link

@otegami otegami commented Dec 24, 2024

Issue

When running tests with Ruby 3.4.0rc1, the following warnings are displayed.

$ rake test
Run options: --seed 46514

/work/ruby/json-stream/lib/json/stream/parser.rb:549: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
/work/ruby/json-stream/lib/json/stream/parser.rb:555: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)

Causes

According to https://bugs.ruby-lang.org/issues/20205, string literals may be frozen by default in future Ruby versions (potentially Ruby 4.0+).
Starting from Ruby 3.4.0, warnings like warning: literal string will be frozen in the future are shown if string literals are mutable.

Solution

We explicitly make string literals mutable using +"string literal" Additionally, we add # frozen_string_literal: true at the top of the affected files and handle the warnings to ensure compatibility with Ruby versions before 3.4.0.

Issue

When running tests with Ruby 3.4.0rc1, the following warnings are displayed.

```console
$ rake test
Run options: --seed 46514

/work/ruby/json-stream/lib/json/stream/parser.rb:549: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
/work/ruby/json-stream/lib/json/stream/parser.rb:555: warning: literal string will be frozen in the future (run with --debug-frozen-string-literal for more information)
```

Cuases

According to https://bugs.ruby-lang.org/issues/20205, string
literals may be frozen by default in future Ruby versions
(potentially Ruby 4.0+).
Starting from Ruby 3.4.0, warnings like `warning: literal string
will be frozen in the future` are shown if string literals are
mutable.

Solution

We explicitly make string literals mutable using `+"string literal"`
Additionally, we add `# frozen_string_literal: true` at the top of
the affected files and handle the warnings to ensure compatibility
with Ruby versions before 3.4.0.
# Avoid state machine for complete UTF-8.
if @buffer.empty?
data.force_encoding(Encoding::UTF_8)
(+data).force_encoding(Encoding::UTF_8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work?

a = "a"
a.force_encoding("ASCII-8BIT")
a.freeze
(+a).force_encoding(Encoding::UTF_8)
p a.encoding # -> #<Encoding:BINARY (ASCII-8BIT)>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it doesn't work. We should assign the result to new variable. I will fix it.

a = "a"
a.force_encoding("ASCII-8BIT")
a.freeze
b = (+a).force_encoding(Encoding::UTF_8)

p a.encoding # -> #<Encoding:BINARY (ASCII-8BIT)>
p b.econding # -> #<Encoding:UTF-8>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dup than + (conditional dup) may be better here because users may not expect that << may change the argument (data).

data = data.dup
data.force_encoding(Encoding::UTF_8)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix: d97d4d2 I see. It totally makes sense to me too!

@sheldonh
Copy link

@dgraham Please consider #10 instead. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants