Project

General

Profile

Feature #18148

Updated by byroot (Jean Boussier) over 2 years ago

### Behavior 

 If passed `freeze: true`, all the deserialized objects should be frozen, and if possible, strings should be deduped. 

 This is similar to the `freeze` option recently added to `JSON` (https://github.com/flori/json/pull/447), `Psych` (https://github.com/ruby/psych/pull/414) and `MessagePack` (https://github.com/msgpack/msgpack-ruby/pull/194). 

 ### Use cases 

 This option is useful in many scenarios: 

   - If the deserialized data is meant to stay on the heap for the lifetime of the program, the string deduplication reduce the memory overhead, and all objects being frozen improve copy on write and ensure that static data isn't accidentally mutated. 
   - If the deserialized data is used in a memory cache or similar, deep freezing it protect against mutation and allow to return the value directly without first deep cloning it. 
   - While not very performant, it can be used as a `deep_freeze` mechanism with `Marshal.load(Marshal.dump(object), freeze: true)`. 



 ### Snippets 


 ```ruby 
 payload = Marshal.dump({"foo" => ["bar"]}) 
 object = Marshal.load(payload, freeze: true) 

 object.frozen? 
 object.dig("foo").frozen? 
 object.dig("foo", 1).frozen? 


 Marshal.load(payload, ->(obj) { raise "unexpected" unless obj.frozen? }, freeze: true) 
 ``` 


 ```ruby 
 def cache_get(key) 
   if entry = in_memory_cache.get(key) 
     return entry 
   end 

   if payload = network_cache.get(key) 
     object = Marshal.load(payload, freeze: true) 
     in_memory_cache.set(key, object) # if the object tree wasn't frozen, we'd need to deep dup to avoid mutation. 
     object 
   end 
 end 
 ```

Back