When loading Yaml contents in Ruby, use the :freeze argument to deep-freeze everything

Posted 4 months ago. Visible to the public.

Ruby methods which load from a Yaml file, like YAML.safe_load or YAML.safe_load_file, support passing freeze: true to deep-freeze the entire contents from the Yaml file.
This is available by default on Ruby 3.0 and newer. On older Rubies, you can install psych 3.2.0 or newer for :freeze support.

As an example, consider the following Yaml file:

---
message:
  - hello
  - universe
foo:
  bar:
    baz: "example"

We can now load it as usual, but pass freeze: true.

>> test = YAML.safe_load_file('example.yml', freeze: true)
=> {"message"=>["hello", "universe"], "foo"=>{"bar"=>{"baz"=>"example"}}}

The Hash itself is frozen:

>> test.frozen?
=> true

And no matter how deep you dig, everything inside that Hash is also frozen.

>> test['message'].frozen?
=> true
>> test['foo']['bar']['baz'].frozen?
=> true

Loading from a file likely means that its contents should be considered immutable (e.g. a configuration), so we recommend you use freeze: true almost always.
Especially use this instead of YAML.safe_load_file(...).freeze which will not freeze any nested objects.

Arne Hartherz
Last edit
4 months ago
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2024-01-18 08:09)