Project

General

Profile

Actions

Feature #18148

closed

Marshal.load freeze option

Added by byroot (Jean Boussier) over 2 years ago. Updated over 2 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:105133]

Description

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

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)
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

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #19427: Marshal.load(source, freeze: true) doesn't freeze in some casesClosedbyroot (Jean Boussier)Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0