[ruby-core:112304] [Ruby master Bug#19427] Marshal.load(source, freeze: true) doesn't freeze in some cases

Issue #19427 has been reported by andrykonchin (Andrew Konchin). ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by Eregon (Benoit Daloze). cc @byroot which implemented this in #18148 ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101748 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by byroot (Jean Boussier). I don't think we can do much about the `_dump` and other callbacks. However I'll try to have a look at the extended objects. ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101749 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by Eregon (Benoit Daloze). byroot (Jean Boussier) wrote in #note-4:
I don't think we can do much about the `_dump` and other callbacks.
Couldn't we at least freeze 1) the object returned by `_load` and 2) the receiver of `marshal_load` after calling `marshal_load`? Yeah we probably can't do much about `a`, `b` or `date` above. For that to work these callbacks would need to know they should freeze and actually do it. ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101751 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by Eregon (Benoit Daloze). If we had (in-place) `deep_freeze` or even just an internal version of it, we could call that after `_load`/`marshal_load` and then it would really be deeply frozen. And that could be efficient by using a flag on objects for "deeply frozen/immutable" (which would also imply shareable). ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101752 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by byroot (Jean Boussier).
`deep_freeze`
As always the tricky part it circular references etc. But I guess in the case of freeze it's easy to use the frozen flag can be used to void cycles. ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101753 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by byroot (Jean Boussier). I have a PR for extended objects: https://github.com/ruby/ruby/pull/7284 Interestingly, the callback wouldn't be called either, so I suppose the bug is similar for `marshal_load` etc. For those I think we could just call `freeze` on the return value, it wouldn't be a deep freeze, but I think that's good enough? ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101775 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by andrykonchin (Andrew Konchin). The issue was closed. Does it mean that current behaviour of `TYPE_USERDEF` and `TYPE_USRMARSHAL` is expected? Or should I create separate issues to track them independently? ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101862 * Author: andrykonchin (Andrew Konchin) * Status: Closed * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by byroot (Jean Boussier). Status changed from Closed to Open The issue closes automatically when a commit is merged with a reference to it. I can re-open, but I'm not super hopeful about fixing these other two cases. As explained, I think the best we can do is shallow freeze. ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101863 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by andrykonchin (Andrew Konchin). Thank you! ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-101869 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by Eregon (Benoit Daloze). Shallow freezing of TYPE_USERDEF and TYPE_USRMARSHAL is not done: ``` 2) Marshal.load when called with freeze: true returns frozen object having #_dump method FAILED Expected #<UserDefined:0x00007f241ebb8e58 @a=:stuff, @b=:stuff>.frozen? to be truthy but was false /home/eregon/code/rubyspec/core/marshal/shared/load.rb:146:in `block (5 levels) in <top (required)>' /home/eregon/code/rubyspec/core/marshal/load_spec.rb:4:in `<top (required)>' 3) Marshal.load when called with freeze: true returns frozen object responding to #marshal_dump and #marshal_load FAILED Expected #<UserMarshal:0x00007f2430a2ab10 @data=:data>.frozen? to be truthy but was false /home/eregon/code/rubyspec/core/marshal/shared/load.rb:151:in `block (5 levels) in <top (required)>' /home/eregon/code/rubyspec/core/marshal/load_spec.rb:4:in `<top (required)>' ``` ```ruby ruby_bug "#19427", "3.1"..."3.3" do it "returns frozen object having #_dump method" do object = Marshal.send(@method, Marshal.dump(UserDefined.new), freeze: true) object.should.frozen? end it "returns frozen object responding to #marshal_dump and #marshal_load" do object = Marshal.send(@method, Marshal.dump(UserMarshal.new), freeze: true) object.should.frozen? end ``` So I reopen to at least shallow-freeze those. ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-102897 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by Eregon (Benoit Daloze). Assignee set to byroot (Jean Boussier) ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-102898 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * Assignee: byroot (Jean Boussier) * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by Eregon (Benoit Daloze). Revert https://github.com/ruby/spec/commit/036134c0c6af8e01ae150db5e2ac6c5d70364a10 once this is fixed ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-102899 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * Assignee: byroot (Jean Boussier) * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/

Issue #19427 has been updated by nagachika (Tomoyuki Chikanaga). Backport changed from 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED, 3.2: REQUIRED to 2.7: DONTNEED, 3.0: DONTNEED, 3.1: WONTFIX, 3.2: WONTFIX I think it's obviously a bug, but I'm concerned that changing the behavior might cause FrozenError in applications. Therefore, I have decided not to backport the changesets related to this issue. Please feel free to raise any objections to this decision. ---------------------------------------- Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some cases https://bugs.ruby-lang.org/issues/19427#change-108312 * Author: andrykonchin (Andrew Konchin) * Status: Closed * Assignee: byroot (Jean Boussier) * ruby -v: 3.1 * Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: WONTFIX, 3.2: WONTFIX ---------------------------------------- I've noticed that the `freeze` option doesn't work in the following cases: - when dumped object extends a module - when dumped object responds to `#marshal_dump` and `#marshal_load` methods - when dumped object responds to `#_dump` method Is it expected behaviour or maybe a known issue? Examples: ```ruby module M end object = Object.new object.extend(M) object = Marshal.load(Marshal.dump(object), freeze: true) object.frozen? # => false ``` ```ruby class UserMarshal attr_accessor :data def initialize @data = 'stuff' end def marshal_dump() :data end def marshal_load(data) @data = data end end object = Marshal.load(Marshal.dump(UserMarshal.new), freeze: true) object.frozen? # => false ``` ```ruby class UserDefined attr_reader :a, :b def initialize @a = 'stuff' @b = @a end def _dump(depth) Marshal.dump [:stuff, :stuff] end def self._load(data) a, b = Marshal.load data obj = allocate obj.instance_variable_set :@a, a obj.instance_variable_set :@b, b obj end end object = Marshal.load(Marshal.dump(UserDefined.new), freeze: true) object.frozen? # => false ``` -- https://bugs.ruby-lang.org/
participants (5)
-
andrykonchin (Andrew Konchin)
-
byroot (Jean Boussier)
-
Eregon (Benoit Daloze)
-
Eregon (Benoit Daloze)
-
nagachika (Tomoyuki Chikanaga)