Bug #11827
closedStringIO with set_encoding broken with enabled frozen string literal
Description
I'm not sure if this the following problem is an expected behavior. But I guess, it is a bug when I run the code below. It throws `set_encoding': can't modify frozen String (RuntimeError).
I wouldn't expect this kind of behavior.
Updated by shugo (Shugo Maeda) over 10 years ago
- Status changed from Open to Feedback
deepj # wrote:
I'm not sure if this the following problem is an expected behavior. But I guess, it is a bug when I run the code below. It throws `set_encoding': can't modify frozen String (RuntimeError).
I wouldn't expect this kind of behavior.
What behavior do you expect?
StringIO is a wrapper to provide IO-like interface for String, so the argument of StringIO.new should not be copied.
If you specify writable mode explicitly, you can get an exception earlier:
Updated by deepj (deepj #) over 10 years ago
Shugo Maeda wrote:
What behavior do you expect?
Not throw the exception in this case. I guess this is a better example https://github.com/rack/rack/blob/master/lib/rack/mock.rb#L139
Here is set an encoding for IO classes included StringIO. When the frozen string literal is enabled it causes a problem obviously. And there is no way (at least I haven't figured out it) how to change an encoding for a StringIO with frozen string. For me it wouldn't be any difference with I have a StringIO with a frozen string, or a File. It's just a interface with same expected behaviour of IO-like classes. In this case a change of encoding. So a string would be mutable in StringIO when it was immutable previously. I might be wrong here.
Updated by naruse (Yui NARUSE) over 10 years ago
deepj # wrote:
Shugo Maeda wrote:
What behavior do you expect?
Not throw the exception in this case. I guess this is a better example https://github.com/rack/rack/blob/master/lib/rack/mock.rb#L139
Here is set an encoding for IO classes included StringIO. When the frozen string literal is enabled it causes a problem obviously. And there is no way (at least I haven't figured out it) how to change an encoding for a StringIO with frozen string. For me it wouldn't be any difference with I have a StringIO with a frozen string, or a File. It's just a interface with same expected behavior of IO-like classes. In this case a change of encoding. So a string would be mutable in StringIO when it was immutable previously. I might be wrong here.
In this case ''.force_encoding(Encoding::ASCII_8BIT) should be String.new.force_encoding(Encoding::ASCII_8BIT)
(or String.new(encoding: Encoding::ASCII_8BIT) for Ruby 2.3)
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.
Updated by shugo (Shugo Maeda) over 10 years ago
Yui NARUSE 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.
FYI, nobu figured out that open-uri depends on the current behavior:
Updated by nobu (Nobuyoshi Nakada) over 10 years ago
- Status changed from Feedback to Closed
Applied in changeset r53188.
stringio.c: separate encoding from buffer
- ext/stringio/stringio.c (strio_set_encoding): add StringIO's own
encoding and separate it from the buffer string to override the
encoding of string when reading. [ruby-core:72189] [Bug #11827]
note that setting the encoding of its buffer string may cause
unpredictable behavior.