Issue #18035 has been updated by maciej.mensfeld (Maciej Mensfeld).


> Should the definition of immutability include making a deep copy of non-immutable objects?

Deep copy or frozen args requirement in the first place.

I think this is a feature that for advanced users can bring a lot of benefits. Many things in dry ecosystem are forfrozen when built (contract classes for example). Could we extend it to include also class and module definitions, so once initialized, cannot be changed?

On one side it would break monkey-patching but at the same time would allow easier (more verbose?) expression of "this is not to be touched" when building libs.

----------------------------------------
Feature #18035: Introduce general model/semantic for immutable by default.
https://bugs.ruby-lang.org/issues/18035#change-93792

* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
It would be good to establish some rules around mutability, immutability, frozen, and deep frozen in Ruby.

I see time and time again, incorrect assumptions about how this works in production code. Constants that aren't really constant, people using `#freeze` incorrectly, etc.

I don't have any particular preference but:

- We should establish consistent patterns where possible, e.g.
  - Objects created by `new` are mutable.
  - Objects created by literal are immutable.

We have problems with how `freeze` works on composite data types, e.g. `Hash#freeze` does not impact children keys/values, same for Array. Do we need to introduce `freeze(true)` or `#deep_freeze` or some other method?

Because of this, frozen does not necessarily correspond to immutable. This is an issue which causes real world problems.

I also propose to codify this where possible, in terms of "this class of object is immutable" should be enforced by the language/runtime, e.g.


```ruby
module Immutable
  def new(...)
    super.freeze
  end
end

class MyImmutableObject
  extend Immutable

  def initialize(x)
    @x = x
  end
  
  def freeze
    return self if frozen?
    
    @x.freeze
    
    super
  end
end

o = MyImmutableObject.new([1, 2, 3])
puts o.frozen?
```

Finally, this area has an impact to thread and fiber safe programming, so it is becoming more relevant and I believe that the current approach which is rather adhoc is insufficient.

I know that it's non-trivial to retrofit existing code, but maybe it can be done via magic comment, etc, which we already did for frozen string literals.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>