Read more

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

Arne Hartherz
January 18, 2024Software engineer at makandra GmbH

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.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

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.

Posted by Arne Hartherz to makandra dev (2024-01-18 09:09)