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

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